├── tests
├── requirements.txt
├── context.py
├── test_read_region.py
├── test_mixed_chunk_types.py
├── test_stream_blocks.py
└── test_benchmark.py
├── MANIFEST.in
├── docs
├── requirements.txt
├── index.rst
├── Makefile
├── api.rst
├── make.bat
├── conf.py
└── _static
│ └── custom.css
├── .gitignore
├── pytest.ini
├── .readthedocs.yml
├── anvil
├── __init__.py
├── legacy.py
├── errors.py
├── versions.py
├── raw_section.py
├── legacy_biomes.json
├── biome.py
├── region.py
├── block.py
├── empty_section.py
├── empty_chunk.py
├── empty_region.py
├── chunk.py
└── legacy_blocks.json
├── examples
├── _path.py
├── cube.py
├── top_view.py
└── basic_world_gen.py
├── setup.py
├── .github
└── workflows
│ └── run-pytest.yml
├── LICENSE
└── README.md
/tests/requirements.txt:
--------------------------------------------------------------------------------
1 | NBT==1.5.1
2 | frozendict==2.0.2
3 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include anvil/legacy_blocks.json
2 | include anvil/legacy_biomes.json
3 |
--------------------------------------------------------------------------------
/docs/requirements.txt:
--------------------------------------------------------------------------------
1 | sphinx-autodoc-typehints==1.10.3
2 | sphinxcontrib-trio==1.1.0
3 |
--------------------------------------------------------------------------------
/tests/context.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__/
2 | textures/
3 | dist/
4 | build/
5 | *.egg-info/
6 | .pytest_cache/
7 | .vscode/
8 | docs/_build/
9 | examples/test_112.py
10 | venv
11 |
--------------------------------------------------------------------------------
/pytest.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | log_cli = True
3 | log_cli_level = INFO
4 | log_cli_format = %(levelname)8s %(message)s
5 | # blame the nbt library
6 | filterwarnings =
7 | ignore::DeprecationWarning
8 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | anvil-parser
2 | ============
3 |
4 | Simple parser for the `Minecraft anvil file format `_
5 |
6 | .. toctree::
7 | :maxdepth: 3
8 |
9 | api
--------------------------------------------------------------------------------
/.readthedocs.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | sphinx:
4 | configuration: docs/conf.py
5 |
6 | python:
7 | version: 3.7
8 | install:
9 | - requirements: docs/requirements.txt
10 | - requirements: tests/requirements.txt
11 |
--------------------------------------------------------------------------------
/anvil/__init__.py:
--------------------------------------------------------------------------------
1 | from .chunk import Chunk
2 | from .block import Block, OldBlock
3 | from .biome import Biome
4 | from .region import Region
5 | from .empty_region import EmptyRegion
6 | from .empty_chunk import EmptyChunk
7 | from .empty_section import EmptySection
8 | from .raw_section import RawSection
9 |
--------------------------------------------------------------------------------
/anvil/legacy.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 |
4 | with open(os.path.join(os.path.dirname(__file__), 'legacy_blocks.json'), 'r') as file:
5 | LEGACY_ID_MAP = json.load(file)
6 |
7 | with open(os.path.join(os.path.dirname(__file__), 'legacy_biomes.json'), 'r') as file:
8 | LEGACY_BIOMES_ID_MAP = {int(k):v for k, v in json.load(file).items()}
--------------------------------------------------------------------------------
/examples/_path.py:
--------------------------------------------------------------------------------
1 | """
2 | This is an utility script to add the parent folder to the path
3 | so i can do `import anvil` in the examples
4 | Code entirely from: https://stackoverflow.com/a/33532002/9124836
5 | """
6 | from inspect import getsourcefile
7 | import os.path
8 | import sys
9 |
10 | current_path = os.path.abspath(getsourcefile(lambda:0))
11 | current_dir = os.path.dirname(current_path)
12 | parent_dir = current_dir[:current_dir.rfind(os.path.sep)]
13 |
14 | sys.path.insert(0, parent_dir)
15 |
--------------------------------------------------------------------------------
/anvil/errors.py:
--------------------------------------------------------------------------------
1 | class OutOfBoundsCoordinates(ValueError):
2 | """Exception used for when coordinates are out of bounds"""
3 |
4 | class ChunkNotFound(Exception):
5 | """Exception used for when a chunk was not found"""
6 |
7 | class EmptySectionAlreadyExists(Exception):
8 | """
9 | Exception used for when trying to add an `EmptySection` to an `EmptyChunk`
10 | and the chunk already has a section with the same Y
11 | """
12 |
13 | class GZipChunkData(Exception):
14 | """Exception used when trying to get chunk data compressed in gzip"""
--------------------------------------------------------------------------------
/tests/test_read_region.py:
--------------------------------------------------------------------------------
1 | import context as _
2 | from anvil import Region
3 | import io
4 | import secrets
5 |
6 | def test_from_filename(tmp_path):
7 | filename = tmp_path / "region.mca"
8 | contents = secrets.token_bytes()
9 |
10 | with open(filename, 'wb') as f:
11 | f.write(contents)
12 |
13 | region = Region.from_file(str(filename))
14 | assert region.data == contents
15 |
16 | def test_from_filelike():
17 | contents = secrets.token_bytes()
18 | filelike = io.BytesIO(contents)
19 |
20 | region = Region.from_file(filelike)
21 | assert region.data == contents
22 |
--------------------------------------------------------------------------------
/examples/cube.py:
--------------------------------------------------------------------------------
1 | import _path
2 | import anvil
3 | from random import choice
4 |
5 | # Create a new region with the `EmptyRegion` class at 0, 0 (in region coords)
6 | region = anvil.EmptyRegion(0, 0)
7 |
8 | # Create `Block` objects that are used to set blocks
9 | stone = anvil.Block('minecraft', 'stone')
10 | dirt = anvil.Block('minecraft', 'dirt')
11 |
12 | # Make a 16x16x16 cube of either stone or dirt blocks
13 | for y in range(16):
14 | for z in range(16):
15 | for x in range(16):
16 | region.set_block(choice((stone, dirt)), x, y, z)
17 |
18 | # Save to a file
19 | region.save('r.0.0.mca')
20 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | import setuptools
2 |
3 | with open('README.md', 'r') as file:
4 | long_description = file.read()
5 |
6 | setuptools.setup(
7 | name='anvil-parser2',
8 | version='0.10.6',
9 | author='0xTiger',
10 | description='A parser for the Minecraft anvil file format, supports all Minecraft verions',
11 | long_description=long_description,
12 | long_description_content_type='text/markdown',
13 | url='https://github.com/0xTiger/anvil-parser2',
14 | packages=setuptools.find_packages(),
15 | classifiers=[
16 | 'Programming Language :: Python :: 3',
17 | 'License :: OSI Approved :: MIT License',
18 | 'Operating System :: OS Independent',
19 | ],
20 | install_requires=[
21 | 'nbt',
22 | 'frozendict',
23 | ],
24 | include_package_data=True
25 | )
26 |
--------------------------------------------------------------------------------
/tests/test_mixed_chunk_types.py:
--------------------------------------------------------------------------------
1 | import context as _
2 | from anvil import Chunk, EmptyChunk, EmptyRegion, Block, Region
3 | import random
4 |
5 | def test_mixed_chunk_types():
6 | colors = ['red', 'orange', 'yellow', 'green']
7 |
8 | region = EmptyRegion(0, 0)
9 |
10 | chunk = EmptyChunk(0, 0)
11 | empty_chunk = EmptyChunk(1, 0)
12 | for i, color in enumerate(colors):
13 | chunk.set_block(Block(color), i, 0, 0)
14 | empty_chunk.set_block(Block(color), i, 0, 0)
15 |
16 | chunk = Chunk(chunk.save())
17 |
18 | region.add_chunk(chunk)
19 | region.add_chunk(empty_chunk)
20 |
21 | region = Region(region.save())
22 |
23 | for i in range(2):
24 | chunk = region.get_chunk(i, 0)
25 | for i, color in enumerate(colors):
26 | assert chunk.get_block(i, 0, 0).id == color
27 |
--------------------------------------------------------------------------------
/docs/api.rst:
--------------------------------------------------------------------------------
1 | API Reference
2 | =============
3 |
4 | Block
5 | -----
6 | .. autoclass:: anvil.Block
7 | :members:
8 |
9 | .. automethod:: __init__
10 |
11 | .. autoclass:: anvil.OldBlock
12 | :members:
13 |
14 | .. automethod:: __init__
15 |
16 | Region
17 | ------
18 | .. autoclass:: anvil.Region
19 | :members:
20 |
21 | Chunk
22 | -----
23 | .. autoclass:: anvil.Chunk
24 | :members:
25 |
26 | Empty
27 | -----
28 |
29 | Region
30 | ~~~~~~
31 | .. autoclass:: anvil.EmptyRegion
32 | :members:
33 |
34 | Chunk
35 | ~~~~~
36 | .. autoclass:: anvil.EmptyChunk
37 | :members:
38 |
39 | Section
40 | ~~~~~~~
41 | .. autoclass:: anvil.EmptySection
42 | :members:
43 |
44 | .. autoclass:: anvil.RawSection
45 | :members:
46 |
47 | Errors
48 | ------
49 | .. automodule:: anvil.errors
50 | :members:
51 | :undoc-members:
52 | :show-inheritance:
53 |
--------------------------------------------------------------------------------
/.github/workflows/run-pytest.yml:
--------------------------------------------------------------------------------
1 | # This workflow will install Python dependencies and run tests with a single version of Python
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
3 |
4 | name: Tests
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 | pull_request:
10 | branches: [ master ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - uses: actions/checkout@v2
19 | - name: Set up Python 3.9
20 | uses: actions/setup-python@v2
21 | with:
22 | python-version: 3.9
23 | - name: Install dependencies
24 | run: |
25 | python -m pip install --upgrade pip
26 | pip install pytest
27 | if [ -f tests/requirements.txt ]; then pip install -r tests/requirements.txt; fi
28 | - name: Test with pytest
29 | run: |
30 | pytest
31 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=.
11 | set BUILDDIR=_build
12 |
13 | if "%1" == "" goto help
14 |
15 | %SPHINXBUILD% >NUL 2>NUL
16 | if errorlevel 9009 (
17 | echo.
18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19 | echo.installed, then set the SPHINXBUILD environment variable to point
20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
21 | echo.may add the Sphinx directory to PATH.
22 | echo.
23 | echo.If you don't have Sphinx installed, grab it from
24 | echo.http://sphinx-doc.org/
25 | exit /b 1
26 | )
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/anvil/versions.py:
--------------------------------------------------------------------------------
1 | # This version removes the chunk's "Level" NBT tag and moves all contained tags to the top level
2 | # https://minecraft.wiki/w/Java_Edition_21w43a
3 | VERSION_21w43a = 2844
4 |
5 | # This version removes block state value stretching from the storage
6 | # so a block value isn't in multiple elements of the array
7 | VERSION_20w17a = 2529
8 |
9 | # This version changes how biomes are stored to allow for biomes at different heights
10 | # https://minecraft.wiki/w/Java_Edition_19w36a
11 | VERSION_19w36a = 2203
12 |
13 | # This is the version where "The Flattening" (https://minecraft.wiki/w/Java_Edition_1.13/Flattening) happened
14 | # where blocks went from numeric ids to namespaced ids (namespace:block_id)
15 | VERSION_17w47a = 1451
16 |
17 | # This represents Versions before 1.9 snapshot 15w32a,
18 | # these snapshots do not have a Data Version so we use -1 since -1 is less than any valid data version.
19 | # https://minecraft.wiki/w/Data_version
20 | VERSION_PRE_15w32a = -1
21 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 mateus
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/top_view.py:
--------------------------------------------------------------------------------
1 | """
2 | Generates a image of the top view of a chunk
3 | Needs a textures folder with a block folder inside
4 | """
5 | import sys
6 | if len(sys.argv) == 1:
7 | print('You must give a region file')
8 | exit()
9 | else:
10 | region = sys.argv[1]
11 | chx = int(sys.argv[2])
12 | chz = int(sys.argv[3])
13 | import os
14 | from PIL import Image
15 | import _path
16 | import anvil
17 |
18 | chunk = anvil.Chunk.from_region(region, chx, chz)
19 | img = Image.new('RGBA', (16*16,16*16))
20 | grid = [[None for i in range(16)] for j in range(16)]
21 | for y in reversed(range(256)):
22 | for z in range(16):
23 | for x in range(16):
24 | b = chunk.get_block(x, y, z).id
25 | if b == 'air' or grid[z][x] is not None:
26 | continue
27 | grid[z][x] = b
28 |
29 | texturesf = os.listdir('textures/block')
30 | textures = {}
31 | for z in range(16):
32 | for x in range(16):
33 | b = grid[z][x]
34 | if b is None:
35 | continue
36 | if b not in textures:
37 | if b+'.png' not in texturesf:
38 | print(f'Skipping {b}')
39 | textures[b] = None
40 | continue
41 | textures[b] = Image.open(f'textures/block/{b}.png')
42 | if textures[b] is None:
43 | continue
44 | img.paste(textures[b], box=(x*16, z*16))
45 |
46 | img.show()
47 |
--------------------------------------------------------------------------------
/anvil/raw_section.py:
--------------------------------------------------------------------------------
1 | from typing import List, Tuple, Sequence, Iterable
2 | from . import EmptySection, Block
3 | from .errors import OutOfBoundsCoordinates
4 | import array
5 | from nbt import nbt
6 |
7 | def bin_append(a, b, length=None):
8 | length = length or b.bit_length()
9 | return (a << length) | b
10 |
11 | class RawSection:
12 | """
13 | Same as :class:`EmptySection` but you manually
14 | set the palette and the blocks array (which instead
15 | of :class:`Block`, it's indexes on the palette)
16 |
17 | Attributes
18 | ----------
19 | y: :class:`int`
20 | Section's Y index
21 | blocks: Iterable[:class:`int`]
22 | Array of palette indexes
23 | _palette: Sequence[:class:`Block`]
24 | Section's palette
25 | """
26 | __slots__ = ('y', '_palette', 'blocks')
27 | def __init__(self, y: int, blocks: Iterable[int], palette: Sequence[Block]):
28 | self.y = y
29 | self.blocks: Iterable[int] = blocks
30 | self._palette: Sequence[Block] = palette
31 |
32 | def palette(self) -> Sequence[Block]:
33 | """Returns ``self._palette``"""
34 | return self._palette
35 |
36 | def blockstates(self, palette: Sequence[Block]=None) -> array.array:
37 | """Refer to :class:`EmptySection.blockstates()`"""
38 | bits = max((len(self._palette) - 1).bit_length(), 4)
39 | states = array.array('Q')
40 | current = 0
41 | current_len = 0
42 | for index in self.blocks:
43 | if current_len + bits > 64:
44 | leftover = 64 - current_len
45 | states.append(bin_append(index & ((1 << leftover) - 1), current, length=current_len))
46 | current = index >> leftover
47 | current_len = bits - leftover
48 | else:
49 | current = bin_append(index, current, length=current_len)
50 | current_len += bits
51 | states.append(current)
52 | return states
53 |
54 | def save(self) -> nbt.TAG_Compound:
55 | """Refer to :class:`EmptySection.save()`"""
56 | return EmptySection.save(self)
57 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # anvil-parser2
2 | [](https://anvil-parser.readthedocs.io/en/latest/?badge=latest)
3 | [](https://github.com/0xTiger/anvil-parser/actions/workflows/run-pytest.yml)
4 | [](https://pypi.org/project/anvil-parser2/)
5 |
6 | A parser for the [Minecraft anvil file format](https://minecraft.wiki/w/Anvil_file_format). This package was forked from [matcool's anvil-parser](https://github.com/matcool/anvil-parser) in order to additionally support minecraft versions 1.18 and above.
7 | # Installation
8 | ```
9 | pip install anvil-parser2
10 | ```
11 |
12 | # Usage
13 | ## Reading
14 | ```python
15 | import anvil
16 |
17 | region = anvil.Region.from_file('r.0.0.mca')
18 |
19 | # You can also provide the region file name instead of the object
20 | chunk = anvil.Chunk.from_region(region, 0, 0)
21 |
22 | # If `section` is not provided, will get it from the y coords
23 | # and assume it's global
24 | block = chunk.get_block(0, 0, 0)
25 |
26 | print(block) #
27 | print(block.id) # air
28 | print(block.properties) # {}
29 | ```
30 | ## Making own regions
31 | ```python
32 | import anvil
33 | from random import choice
34 |
35 | # Create a new region with the `EmptyRegion` class at 0, 0 (in region coords)
36 | region = anvil.EmptyRegion(0, 0)
37 |
38 | # Create `Block` objects that are used to set blocks
39 | stone = anvil.Block('minecraft', 'stone')
40 | dirt = anvil.Block('minecraft', 'dirt')
41 |
42 | # Make a 16x16x16 cube of either stone or dirt blocks
43 | for y in range(16):
44 | for z in range(16):
45 | for x in range(16):
46 | region.set_block(choice((stone, dirt)), x, y, z)
47 |
48 | # Save to a file
49 | region.save('r.0.0.mca')
50 | ```
51 | # Todo
52 | *things to do before 1.0.0*
53 | - [x] Proper documentation
54 | - [x] Biomes
55 | - [x] CI
56 | - [ ] More tests
57 | - [ ] Tests for 20w17a+ BlockStates format
58 | # Note
59 | Testing done in 1.14.4 - 1.21, should work fine for other versions.
60 |
--------------------------------------------------------------------------------
/anvil/legacy_biomes.json:
--------------------------------------------------------------------------------
1 | {
2 | "0": "ocean",
3 | "4": "forest",
4 | "7": "river",
5 | "10": "frozen_ocean",
6 | "11": "frozen_river",
7 | "16": "beach",
8 | "24": "deep_ocean",
9 | "25": "stone_shore",
10 | "26": "snowy_beach",
11 | "44": "warm_ocean",
12 | "45": "lukewarm_ocean",
13 | "46": "cold_ocean",
14 | "47": "deep_warm_ocean",
15 | "48": "deep_lukewarm_ocean",
16 | "49": "deep_cold_ocean",
17 | "50": "deep_frozen_ocean",
18 | "18": "wooded_hills",
19 | "132": "flower_forest",
20 | "27": "birch_forest",
21 | "28": "birch_forest_hills",
22 | "155": "tall_birch_forest",
23 | "156": "tall_birch_hills",
24 | "29": "dark_forest",
25 | "157": "dark_forest_hills",
26 | "21": "jungle",
27 | "22": "jungle_hills",
28 | "149": "modified_jungle",
29 | "23": "jungle_edge",
30 | "151": "modified_jungle_edge",
31 | "168": "bamboo_jungle",
32 | "169": "bamboo_jungle_hills",
33 | "5": "taiga",
34 | "19": "taiga_hills",
35 | "133": "taiga_mountains",
36 | "30": "snowy_taiga",
37 | "31": "snowy_taiga_hills",
38 | "158": "snowy_taiga_mountains",
39 | "32": "giant_tree_taiga",
40 | "33": "giant_tree_taiga_hills",
41 | "160": "giant_spruce_taiga",
42 | "161": "giant_spruce_taiga_hills",
43 | "14": "mushroom_fields",
44 | "15": "mushroom_field_shore",
45 | "6": "swamp",
46 | "134": "swamp_hills",
47 | "35": "savanna",
48 | "36": "savanna_plateau",
49 | "163": "shattered_savanna",
50 | "164": "shattered_savanna_plateau",
51 | "1": "plains",
52 | "129": "sunflower_plains",
53 | "2": "desert",
54 | "17": "desert_hills",
55 | "130": "desert_lakes",
56 | "12": "snowy_tundra",
57 | "13": "snowy_mountains",
58 | "140": "ice_spikes",
59 | "3": "mountains",
60 | "34": "wooded_mountains",
61 | "131": "gravelly_mountains",
62 | "162": "modified_gravelly_mountains",
63 | "20": "mountain_edge",
64 | "37": "badlands",
65 | "39": "badlands_plateau",
66 | "167": "modified_badlands_plateau",
67 | "38": "wooded_badlands_plateau",
68 | "166": "modified_wooded_badlands_plateau",
69 | "165": "eroded_badlands",
70 | "8": "nether",
71 | "9": "the_end",
72 | "40": "small_end_islands",
73 | "41": "end_midlands",
74 | "42": "end_highlands",
75 | "43": "end_barrens",
76 | "170": "soul_sand_valley",
77 | "171": "crimson_forest",
78 | "172": "warped_forest",
79 | "127": "the_void",
80 | "173": "basalt_deltas"
81 | }
--------------------------------------------------------------------------------
/anvil/biome.py:
--------------------------------------------------------------------------------
1 | from .legacy import LEGACY_BIOMES_ID_MAP
2 |
3 | class Biome:
4 | """
5 | Represents a minecraft biome.
6 |
7 | Attributes
8 | ----------
9 | namespace: :class:`str`
10 | Namespace of the biome, most of the time this is ``minecraft``
11 | id: :class:`str`
12 | ID of the biome, for example: forest, warm_ocean, etc...
13 | """
14 | __slots__ = ('namespace', 'id')
15 |
16 | def __init__(self, namespace: str, biome_id: str=None):
17 | """
18 | Parameters
19 | ----------
20 | namespace
21 | Namespace of the biome. If no biome_id is given, assume this is ``biome_id`` and set namespace to ``"minecraft"``
22 | biome_id
23 | ID of the biome
24 | """
25 | if biome_id is None:
26 | self.namespace = 'minecraft'
27 | self.id = namespace
28 | else:
29 | self.namespace = namespace
30 | self.id = biome_id
31 |
32 | def name(self) -> str:
33 | """
34 | Returns the biome in the ``minecraft:biome_id`` format
35 | """
36 | return self.namespace + ':' + self.id
37 |
38 | def __repr__(self):
39 | return f'Biome({self.name()})'
40 |
41 | def __eq__(self, other):
42 | if not isinstance(other, Biome):
43 | return False
44 | return self.namespace == other.namespace and self.id == other.id
45 |
46 | def __hash__(self):
47 | return hash(self.name())
48 |
49 | @classmethod
50 | def from_name(cls, name: str):
51 | """
52 | Creates a new Biome from the format: ``namespace:biome_id``
53 |
54 | Parameters
55 | ----------
56 | name
57 | Biome in said format
58 | """
59 | namespace, biome_id = name.split(':')
60 | return cls(namespace, biome_id)
61 |
62 | @classmethod
63 | def from_numeric_id(cls, biome_id: int):
64 | """
65 | Creates a new Biome from the numeric biome_id format
66 |
67 | Parameters
68 | ----------
69 | biome_id
70 | Numeric ID of the biome
71 | """
72 | if biome_id not in LEGACY_BIOMES_ID_MAP:
73 | raise KeyError(f'Biome {biome_id} not found')
74 | name = LEGACY_BIOMES_ID_MAP[biome_id]
75 | return cls('minecraft', name)
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # This file only contains a selection of the most common options. For a full
4 | # list see the documentation:
5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
6 |
7 | # -- Path setup --------------------------------------------------------------
8 |
9 | # If extensions (or modules to document with autodoc) are in another directory,
10 | # add these directories to sys.path here. If the directory is relative to the
11 | # documentation root, use os.path.abspath to make it absolute, like shown here.
12 | #
13 | import os
14 | import sys
15 | sys.path.insert(0, os.path.abspath('../'))
16 |
17 |
18 | # -- Project information -----------------------------------------------------
19 |
20 | project = 'anvil-parser'
21 | copyright = '2020, mat'
22 | author = 'mat'
23 |
24 | # The full version, including alpha/beta/rc tags
25 | release = '0.4.0'
26 |
27 |
28 | # -- General configuration ---------------------------------------------------
29 |
30 | # Add any Sphinx extension module names here, as strings. They can be
31 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
32 | # ones.
33 | extensions = [
34 | 'sphinx.ext.autodoc',
35 | 'sphinx.ext.napoleon',
36 | 'sphinx.ext.intersphinx',
37 | 'sphinx_autodoc_typehints',
38 | 'sphinxcontrib_trio'
39 | ]
40 |
41 | intersphinx_mapping = {'py': ('https://docs.python.org/3', None)}
42 |
43 | napoleon_google_docstring = False
44 |
45 | # Add any paths that contain templates here, relative to this directory.
46 | templates_path = []
47 |
48 | # List of patterns, relative to source directory, that match files and
49 | # directories to ignore when looking for source files.
50 | # This pattern also affects html_static_path and html_extra_path.
51 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
52 |
53 |
54 | # -- Options for HTML output -------------------------------------------------
55 |
56 | # The theme to use for HTML and HTML Help pages. See the documentation for
57 | # a list of builtin themes.
58 | #
59 | html_theme = 'alabaster'
60 |
61 | # Add any paths that contain custom static files (such as style sheets) here,
62 | # relative to this directory. They are copied after the builtin static files,
63 | # so a file named "default.css" will overwrite the builtin "default.css".
64 | html_static_path = ['_static']
65 |
--------------------------------------------------------------------------------
/examples/basic_world_gen.py:
--------------------------------------------------------------------------------
1 | """
2 | Basic terrain generation made to test out EmptyRegion and related
3 | Needs the `opensimplex` package to work
4 |
5 | Generated terrain is 128x128 blocks and in the North-West corner
6 | """
7 | import _path
8 | import anvil
9 | from opensimplex import OpenSimplex
10 | import random
11 | import math
12 |
13 | noise = OpenSimplex()
14 |
15 | region = anvil.EmptyRegion(0, 0)
16 | grass = anvil.Block('minecraft', 'grass_block')
17 | dirt = anvil.Block('minecraft', 'dirt')
18 | glass = anvil.Block('minecraft', 'glass')
19 | oak_log_up = anvil.Block('minecraft', 'oak_log', properties={'axis': 'y'})
20 | oak_leaves = anvil.Block('minecraft', 'oak_leaves', properties={'persistent': True})
21 |
22 | grass_plant = anvil.Block('minecraft', 'grass')
23 | poppy = anvil.Block('minecraft', 'poppy')
24 | dandelion = anvil.Block('minecraft', 'dandelion')
25 | tall_grass_l = anvil.Block('minecraft', 'tall_grass', properties={'half': 'lower'})
26 | tall_grass_u = anvil.Block('minecraft', 'tall_grass', properties={'half': 'upper'})
27 |
28 | scale = 0.01
29 | plant_scale = 1
30 | xoff = region.x * 512
31 | zoff = region.z * 512
32 | random.seed(0)
33 | for z in range(128):
34 | for x in range(128):
35 | x += xoff
36 | z += zoff
37 | v = noise.noise2d(x*scale, z*scale)
38 | v = (v + 1) / 2 # now its from 0 to 1
39 | v = math.floor(v * 100)
40 | region.set_block(grass, x, v, z)
41 | if v > 0:
42 | region.set_block(dirt, x, v-1, z)
43 | n = noise.noise2d(x*plant_scale+100, z*plant_scale)
44 | if n > 0.4:
45 | # flower
46 | if random.random() > 0.95:
47 | region.set_block(random.choice((poppy, dandelion)), x, v+1, z)
48 | else:
49 | if random.random() > 0.9:
50 | region.set_block(tall_grass_l, x, v+1, z)
51 | region.set_block(tall_grass_u, x, v+2, z)
52 | else:
53 | region.set_block(grass_plant, x, v+1, z)
54 | # Tree
55 | if random.random() > 0.99:
56 | region.fill(oak_leaves, x-2, v+4, z-2, x+2, v+5, z+2, ignore_outside=True)
57 | for y in range(6):
58 | region.set_if_inside(oak_log_up, x, v+y+1, z)
59 | region.set_if_inside(oak_leaves, x, v+7, z)
60 | for y in range(2):
61 | region.set_if_inside(oak_leaves, x+1, v+6+y, z)
62 | region.set_if_inside(oak_leaves, x , v+6+y, z+1)
63 | region.set_if_inside(oak_leaves, x-1, v+6+y, z)
64 | region.set_if_inside(oak_leaves, x , v+6+y, z-1)
65 |
66 | save = region.save('r.0.0.mca')
67 |
--------------------------------------------------------------------------------
/tests/test_stream_blocks.py:
--------------------------------------------------------------------------------
1 | import context as _
2 | from anvil import EmptyRegion, Region, Block
3 |
4 | def coord_to_index(x, y, z):
5 | return y * 16 * 16 + z * 16 + x
6 |
7 | def test_4bits():
8 | region = EmptyRegion(0, 0)
9 |
10 | region.set_block(Block('minecraft', 'stone'), 0, 0, 0)
11 | region.set_block(Block('minecraft', 'dirt'), 1, 0, 0)
12 | region.set_block(Block('minecraft', 'oak_planks'), 2, 0, 0)
13 | region.set_block(Block('minecraft', 'sand'), 10, 7, 5)
14 | region.set_block(Block('minecraft', 'white_wool'), 8, 6, 0)
15 | region.set_block(Block('minecraft', 'bedrock'), 15, 15, 15)
16 |
17 | region = Region(region.save())
18 |
19 | for i, block in enumerate(region.get_chunk(0, 0).stream_blocks()):
20 | if i == 0:
21 | assert block.id == 'stone'
22 | elif i == 1:
23 | assert block.id == 'dirt'
24 | elif i == 2:
25 | assert block.id == 'oak_planks'
26 | elif i == coord_to_index(10, 7, 5):
27 | assert block.id == 'sand'
28 | elif i == coord_to_index(15, 15, 15):
29 | assert block.id == 'bedrock'
30 | elif i == coord_to_index(8, 6, 0):
31 | assert block.id == 'white_wool'
32 | else:
33 | assert block.id == 'air'
34 |
35 | def test_5bits():
36 | from random import randint
37 | region = EmptyRegion(0, 0)
38 |
39 | blocks = 'stone,dirt,oak_planks,sand,bedrock,white_wool,red_wool,green_wool,sponge,awesome,these,dont,need,to,exist,foo,bar'.split(',')
40 | positions = [(randint(0, 15), randint(0, 15), randint(0, 15)) for _ in range(len(blocks))]
41 | for block, pos in zip(blocks, positions):
42 | region.set_block(Block('minecraft', block), *pos)
43 |
44 | region = Region(region.save())
45 |
46 | for i, block in enumerate(region.get_chunk(0, 0).stream_blocks()):
47 | if block.id in blocks:
48 | assert coord_to_index(*positions[blocks.index(block.id)]) == i
49 | else:
50 | assert block.id == 'air'
51 |
52 | def test_index():
53 | region = EmptyRegion(0, 0)
54 |
55 | region.set_block(Block('minecraft', 'dirt'), 2, 0, 0)
56 | region.set_block(Block('minecraft', 'stone'), 3, 0, 0)
57 | blocks = 'stone,dirt,oak_planks,sand,bedrock'.split(',')
58 | for i, block in enumerate(blocks):
59 | region.set_block(Block('minecraft', block), i % 16, 0, i // 16)
60 |
61 | region = Region(region.save())
62 |
63 | for i, block in enumerate(region.get_chunk(0, 0).stream_blocks(index=2)):
64 | i += 2
65 | if i < len(blocks):
66 | assert block.id == blocks[i]
67 | else:
68 | assert block.id == 'air'
69 |
70 | def test_index_5bits():
71 | region = EmptyRegion(0, 0)
72 |
73 | region.set_block(Block('minecraft', 'dirt'), 2, 0, 0)
74 | region.set_block(Block('minecraft', 'stone'), 3, 0, 0)
75 | blocks = 'stone,dirt,oak_planks,sand,bedrock,white_wool,red_wool,green_wool,sponge,awesome,these,dont,need,to,exist,foo,bar'.split(',')
76 | for i, block in enumerate(blocks):
77 | region.set_block(Block('minecraft', block), i % 16, 0, i // 16)
78 |
79 | region = Region(region.save())
80 |
81 | for i, block in enumerate(region.get_chunk(0, 0).stream_blocks(index=17)):
82 | i += 17
83 | if i < len(blocks):
84 | assert block.id == blocks[i]
85 | else:
86 | assert block.id == 'air'
87 |
--------------------------------------------------------------------------------
/anvil/region.py:
--------------------------------------------------------------------------------
1 | from typing import Tuple, Union, BinaryIO
2 | from nbt import nbt
3 | import zlib
4 | from io import BytesIO
5 | import anvil
6 | from .errors import GZipChunkData
7 |
8 | class Region:
9 | """
10 | Read-only region
11 |
12 | Attributes
13 | ----------
14 | data: :class:`bytes`
15 | Region file (``.mca``) as bytes
16 | """
17 | __slots__ = ('data',)
18 | def __init__(self, data: bytes):
19 | """Makes a Region object from data, which is the region file content"""
20 | self.data = data
21 |
22 | @staticmethod
23 | def header_offset(chunk_x: int, chunk_z: int) -> int:
24 | """
25 | Returns the byte offset for given chunk in the header
26 |
27 | Parameters
28 | ----------
29 | chunk_x
30 | Chunk's X value
31 | chunk_z
32 | Chunk's Z value
33 | """
34 | return 4 * (chunk_x % 32 + chunk_z % 32 * 32)
35 |
36 | def chunk_location(self, chunk_x: int, chunk_z: int) -> Tuple[int, int]:
37 | """
38 | Returns the chunk offset in the 4KiB sectors from the start of the file,
39 | and the length of the chunk in sectors of 4KiB
40 |
41 | Will return ``(0, 0)`` if chunk hasn't been generated yet
42 |
43 | Parameters
44 | ----------
45 | chunk_x
46 | Chunk's X value
47 | chunk_z
48 | Chunk's Z value
49 | """
50 | b_off = self.header_offset(chunk_x, chunk_z)
51 | off = int.from_bytes(self.data[b_off : b_off + 3], byteorder='big')
52 | sectors = self.data[b_off + 3]
53 | return (off, sectors)
54 |
55 | def chunk_data(self, chunk_x: int, chunk_z: int) -> nbt.NBTFile:
56 | """
57 | Returns the NBT data for a chunk
58 |
59 | Parameters
60 | ----------
61 | chunk_x
62 | Chunk's X value
63 | chunk_z
64 | Chunk's Z value
65 |
66 | Raises
67 | ------
68 | anvil.GZipChunkData
69 | If the chunk's compression is gzip
70 | """
71 | off = self.chunk_location(chunk_x, chunk_z)
72 | # (0, 0) means it hasn't generated yet, aka it doesn't exist yet
73 | if off == (0, 0):
74 | return
75 | off = off[0] * 4096
76 | length = int.from_bytes(self.data[off:off + 4], byteorder='big')
77 | compression = self.data[off + 4] # 2 most of the time
78 | if compression == 1:
79 | raise GZipChunkData('GZip is not supported')
80 | compressed_data = self.data[off + 5 : off + 5 + length - 1]
81 | return nbt.NBTFile(buffer=BytesIO(zlib.decompress(compressed_data)))
82 |
83 | def get_chunk(self, chunk_x: int, chunk_z: int) -> 'anvil.Chunk':
84 | """
85 | Returns the chunk at given coordinates,
86 | same as doing ``Chunk.from_region(region, chunk_x, chunk_z)``
87 |
88 | Parameters
89 | ----------
90 | chunk_x
91 | Chunk's X value
92 | chunk_z
93 | Chunk's Z value
94 |
95 |
96 | :rtype: :class:`anvil.Chunk`
97 | """
98 | return anvil.Chunk.from_region(self, chunk_x, chunk_z)
99 |
100 | @classmethod
101 | def from_file(cls, file: Union[str, BinaryIO]):
102 | """
103 | Creates a new region with the data from reading the given file
104 |
105 | Parameters
106 | ----------
107 | file
108 | Either a file path or a file object
109 | """
110 | if isinstance(file, str):
111 | with open(file, 'rb') as f:
112 | return cls(data=f.read())
113 | else:
114 | return cls(data=file.read())
115 |
--------------------------------------------------------------------------------
/tests/test_benchmark.py:
--------------------------------------------------------------------------------
1 | import context as _
2 | from anvil import EmptyRegion, Block, RawSection
3 | import math
4 | import time
5 | import logging
6 | import array
7 |
8 | LOGGER = logging.getLogger(__name__)
9 |
10 | def test_benchmark():
11 | region = EmptyRegion(0, 0)
12 |
13 | block = Block('iron_block')
14 |
15 | def func(x: int, z: int) -> int:
16 | return math.sin(x * x + z * z) * 0.5 + 0.5
17 |
18 | w = 256
19 | scale = 0.05
20 | y_scale = 15
21 |
22 | start = time.time()
23 | for x in range(w):
24 | for z in range(w):
25 | u = x - w / 2
26 | v = z - w / 2
27 | y = int(func(u * scale, v * scale) * y_scale)
28 | region.set_block(block, x, y, z)
29 | end = time.time()
30 |
31 | LOGGER.info(f'Generating took: {end - start:.3f}s')
32 |
33 | times = []
34 | n = 3
35 | for _ in range(n):
36 | start = time.time()
37 | region.save()
38 | end = time.time()
39 | times.append(end - start)
40 |
41 | LOGGER.info(f'Saving (average of {n}) took: {sum(times) / len(times):.3f}s')
42 |
43 | def test_raw_section():
44 | region = EmptyRegion(0, 0)
45 |
46 | block = Block('iron_block')
47 | air = Block('air')
48 | palette = (air, block)
49 |
50 | def func(x: int, z: int) -> int:
51 | return math.sin(x * x + z * z) * 0.5 + 0.5
52 |
53 | w = 256
54 | chunk_w = w // 16
55 | scale = 0.05
56 | y_scale = 15
57 |
58 | start = time.time()
59 |
60 | # from 0 to y_scale
61 | heights = array.array('B')
62 | for z in range(w):
63 | for x in range(w):
64 | u = z - w / 2
65 | v = x - w / 2
66 | height = int(func(u * scale, v * scale) * y_scale)
67 | heights.append(height)
68 |
69 | for chunk_x in range(chunk_w):
70 | for chunk_z in range(chunk_w):
71 | blocks = array.array('B')
72 | for y in range(16):
73 | for z in range(16):
74 | for x in range(16):
75 | rx = x + chunk_x * 16
76 | rz = z + chunk_z * 16
77 | i = rz * w + rx
78 | height = heights[i]
79 | if y == height:
80 | blocks.append(1)
81 | else:
82 | blocks.append(0)
83 | region.add_section(RawSection(0, blocks, palette), chunk_x, chunk_z)
84 |
85 | end = time.time()
86 |
87 | LOGGER.info(f'Generating took: {end - start:.3f}s')
88 |
89 | times = []
90 | n = 3
91 | for _ in range(n):
92 | start = time.time()
93 | region.save()
94 | end = time.time()
95 | times.append(end - start)
96 |
97 | LOGGER.info(f'Saving (average of {n}) took: {sum(times) / len(times):.3f}s')
98 |
99 | def test_raw_section_simple():
100 | region = EmptyRegion(0, 0)
101 |
102 | air = Block('air')
103 | palette = (air, Block('white_concrete'), Block('light_gray_concrete'), Block('gray_concrete'))
104 |
105 | blocks = array.array('B')
106 | for z in range(16):
107 | for x in range(16):
108 | d = x * x + z * z
109 | if d < 25:
110 | blocks.append(1)
111 | elif d < 100:
112 | blocks.append(2)
113 | elif d < 225:
114 | blocks.append(3)
115 | else:
116 | blocks.append(0)
117 |
118 | blocks.extend(0 for _ in range(16 * 16 * 16 - len(blocks)))
119 |
120 | assert len(blocks) == 16 * 16 * 16
121 |
122 | section = RawSection(0, blocks, palette)
123 | region.add_section(section, 0, 0)
124 |
125 | region.save()
126 |
--------------------------------------------------------------------------------
/anvil/block.py:
--------------------------------------------------------------------------------
1 | from nbt import nbt
2 | from frozendict import frozendict
3 | from .legacy import LEGACY_ID_MAP
4 |
5 | class Block:
6 | """
7 | Represents a minecraft block.
8 |
9 | Attributes
10 | ----------
11 | namespace: :class:`str`
12 | Namespace of the block, most of the time this is ``minecraft``
13 | id: :class:`str`
14 | ID of the block, for example: stone, diamond_block, etc...
15 | properties: :class:`dict`
16 | Block properties as a dict
17 | """
18 | __slots__ = ('namespace', 'id', 'properties')
19 |
20 | def __init__(self, namespace: str, block_id: str=None, properties: dict=None):
21 | """
22 | Parameters
23 | ----------
24 | namespace
25 | Namespace of the block. If no block_id is given, assume this is ``block_id`` and set namespace to ``"minecraft"``
26 | block_id
27 | ID of the block
28 | properties
29 | Block properties
30 | """
31 | if block_id is None:
32 | self.namespace = 'minecraft'
33 | self.id = namespace
34 | else:
35 | self.namespace = namespace
36 | self.id = block_id
37 | self.properties = properties or {}
38 |
39 | def name(self) -> str:
40 | """
41 | Returns the block in the ``minecraft:block_id`` format
42 | """
43 | return self.namespace + ':' + self.id
44 |
45 | def __repr__(self):
46 | return f'Block({self.name()})'
47 |
48 | def __eq__(self, other):
49 | if not isinstance(other, Block):
50 | return False
51 | return self.namespace == other.namespace and self.id == other.id and self.properties == other.properties
52 |
53 | def __hash__(self):
54 | return hash(self.name()) ^ hash(frozendict(self.properties))
55 |
56 | @classmethod
57 | def from_name(cls, name: str, *args, **kwargs):
58 | """
59 | Creates a new Block from the format: ``namespace:block_id``
60 |
61 | Parameters
62 | ----------
63 | name
64 | Block in said format
65 | , args, kwargs
66 | Will be passed on to the main constructor
67 | """
68 | namespace, block_id = name.split(':')
69 | return cls(namespace, block_id, *args, **kwargs)
70 |
71 | @classmethod
72 | def from_palette(cls, tag: nbt.TAG_Compound):
73 | """
74 | Creates a new Block from the tag format on Section.Palette
75 |
76 | Parameters
77 | ----------
78 | tag
79 | Raw tag from a section's palette
80 | """
81 | name = tag['Name'].value
82 | properties = dict(tag.get('Properties', dict()))
83 | return cls.from_name(name, properties=properties)
84 |
85 | @classmethod
86 | def from_numeric_id(cls, block_id: int, data: int=0):
87 | """
88 | Creates a new Block from the block_id:data fromat used pre-flattening (pre-1.13)
89 |
90 | Parameters
91 | ----------
92 | block_id
93 | Numeric ID of the block
94 | data
95 | Numeric data, used to represent variants of the block
96 | """
97 | # See https://minecraft.wiki/w/Java_Edition_data_value/Pre-flattening
98 | # and https://minecraft.wiki/w/Java_Edition_data_value for current values
99 | key = f'{block_id}:{data}'
100 | if key not in LEGACY_ID_MAP:
101 | raise KeyError(f'Block {key} not found')
102 | name, properties = LEGACY_ID_MAP[key]
103 | return cls('minecraft', name, properties=properties)
104 |
105 |
106 | class OldBlock:
107 | """
108 | Represents a pre 1.13 minecraft block, with a numeric id.
109 |
110 | Attributes
111 | ----------
112 | id: :class:`int`
113 | Numeric ID of the block
114 | data: :class:`int`
115 | The block data, used to represent variants of the block
116 | """
117 | __slots__ = ('id', 'data')
118 |
119 | def __init__(self, block_id: int, data: int=0):
120 | """
121 | Parameters
122 | ----------
123 | block_id
124 | ID of the block
125 | data
126 | Block data
127 | """
128 | self.id = block_id
129 | self.data = data
130 |
131 | def convert(self) -> Block:
132 | return Block.from_numeric_id(self.id, self.data)
133 |
134 | def __repr__(self):
135 | return f'OldBlock(id={self.id}, data={self.data})'
136 |
137 | def __eq__(self, other):
138 | if isinstance(other, int):
139 | return self.id == other
140 | elif not isinstance(other, Block):
141 | return False
142 | else:
143 | return self.id == other.id and self.data == other.data
144 |
145 | def __hash__(self):
146 | return hash(self.id) ^ hash(self.data)
147 |
--------------------------------------------------------------------------------
/docs/_static/custom.css:
--------------------------------------------------------------------------------
1 | /*
2 | Theme is 99.9% https://userstyles.org/styles/170804/dark-discord-py-rewrite-docs
3 | just has a few tweaks so it works on alabaster
4 | */
5 |
6 | body {
7 | font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu;
8 | font-size: 1.0em;
9 |
10 | /* Scrolling: Firefox */
11 | scrollbar-width: 10px;
12 | scrollbar-color: #2C2F33 #23272A; /* Thumb Track */
13 | }
14 |
15 | h1, h2 {
16 | font-family: -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu !important;
17 | }
18 |
19 | /* Dark */
20 | .indexwrapper,
21 | body {
22 | background-color: #23272A; /* Dark 1 */
23 | color: #dcddde; /* Light 1 */
24 | }
25 |
26 | div.body,
27 | .rst-versions.rst-badge .rst-current-version {
28 | background-color: #2C2F33; /* Dark 2 */
29 | color: #dcddde; /* Light 1 */
30 | }
31 |
32 | .active {
33 | background-color: #2C2F33; /* Dark 2 */
34 | border-left: 5px solid #2C2F33; /* Dark 2 */
35 | }
36 |
37 | /* Get rid of extra bgs */
38 | tt,
39 | code,
40 | div.highlight {
41 | background-color: transparent;
42 | }
43 |
44 | /* Light font for dark bg */
45 | div.sphinxsidebar a,
46 | div.sphinxsidebar h3 a,
47 | div.sphinxsidebar h3,
48 | div.sphinxsidebar h4,
49 | div.sphinxsidebar ul,
50 | div.body h1,
51 | div.body h2,
52 | div.body h3,
53 | div.body h4 {
54 | color: #dcddde;
55 | }
56 |
57 | /* Primary color */
58 | a {
59 | color: #7289da;
60 | }
61 |
62 | a:hover {
63 | color: #7d96f0;
64 | }
65 |
66 | /* Dark bg, light font combo */
67 | dl.describe > dt,
68 | dl.function > dt,
69 | dl.attribute > dt,
70 | dl.classmethod > dt,
71 | dl.method > dt,
72 | dl.class > dt,
73 | dl.exception > dt,
74 | .container.operations > dl.describe > dt,
75 | table.docutils thead,
76 | table.docutils tfoot,
77 | table.docutils thead tr th,
78 | code.sig-prename, code.sig-name {
79 | background-color: #23272A; /* Dark 1 */
80 | color: #dcddde; /* Light 1 */
81 | }
82 |
83 | pre {
84 | background-color: #23272A; /* Dark 1 */
85 | color: #dcddde; /* Light 1 */
86 | border: 1px solid rgba(32, 34, 37, .3);
87 | }
88 |
89 | /* Custom colors */
90 | div.important,
91 | div.note,
92 | div.hint,
93 | div.tip,
94 | highlight,
95 | div.sphinxsidebar input {
96 | background-color: #23272A; /* Dark 1 */
97 | border: 1px solid #959595;
98 | color: #839496;
99 | }
100 |
101 | div.attention,
102 | div.warning,
103 | div.caution,
104 | div.seealso {
105 | background-color: #665623;
106 | }
107 |
108 | div.helpful {
109 | background-color: #162f44;
110 | border: 1px solid #4478ac;
111 | }
112 |
113 | div.danger,
114 | div.error {
115 | background-color: #401414;
116 | border: 1px solid #f66;
117 | }
118 |
119 | .container.operations::before {
120 | color: #dcddde; /* Light 1 */
121 | }
122 |
123 | .highlight .k,
124 | .highlight .ow,
125 | .highlight .nb,
126 | .highlight .kc,
127 | .highlight .bp {
128 | color: #00ae32;
129 | }
130 |
131 | .highlight .nf {
132 | color: #5183ff;
133 | }
134 |
135 | .highlight .hll {
136 | background-color: #0076ff30;
137 | }
138 | /* Rounding */
139 | div.body,
140 | div.admonition,
141 | dl.describe > dt, dl.function > dt, dl.attribute > dt, dl.classmethod > dt, dl.method > dt, dl.class > dt, dl.exception > dt,
142 | .container.operations,
143 | .rst-versions.rst-badge .rst-current-version,
144 | .active,
145 | pre,
146 | img {
147 | border-radius: 5px;
148 | }
149 |
150 | div.sphinxsidebar #searchbox input[type="text"] {
151 | border-top-left-radius: 5px;
152 | border-bottom-left-radius: 5px;
153 | }
154 |
155 | div.sphinxsidebar #searchbox input[type="submit"] {
156 | border-top-right-radius: 5px;
157 | border-bottom-right-radius: 5px;
158 | }
159 |
160 | dl.describe > dt, dl.function > dt, dl.attribute > dt, dl.classmethod > dt, dl.method > dt, dl.class > dt, dl.exception > dt {
161 | padding: 2px 10px;
162 | }
163 |
164 | /* Scrolling: Chrome etc */
165 | ::-webkit-scrollbar {
166 | width: 10px;
167 | }
168 |
169 | ::-webkit-scrollbar-track {
170 | background: #23272A; /* Dark 1 */
171 | }
172 |
173 | ::-webkit-scrollbar-thumb {
174 | background: #2C2F33; /* Dark 2 */
175 | border-radius: 5px;
176 | }
177 |
178 | ::-webkit-scrollbar-thumb:hover {
179 | background: #2C2F33; /* Dark 2 */
180 | }
181 |
182 | div.sphinxsidebarwrapper {
183 | padding-right: 10px;
184 | box-sizing: border-box;
185 | }
186 |
187 | div.sphinxsidebarwrapper:hover {
188 | padding-right: 0;
189 | overflow-y: scroll;
190 | }
191 |
192 | /* My changes */
193 |
194 | div.document {
195 | width: 1000px;
196 | min-width: 500px;
197 | max-width: 1200px;
198 | }
199 |
200 | div.body {
201 | width: 800px;
202 | min-width: 500px;
203 | max-width: 1000px;
204 |
205 | padding-top: 10px;
206 | padding-bottom: 10px;
207 | }
208 |
209 | code.xref {
210 | background: transparent;
211 | color: #7289da;
212 | font-weight: normal;
213 | text-decoration: none;
214 | border-bottom: none;
215 | }
216 |
217 | code.xref:hover > span.pre {
218 | background: transparent;
219 | text-decoration: underline;
220 | }
221 |
222 | a.reference:hover, code.xref:hover {
223 | background: transparent;
224 | }
225 |
226 | code.literal:not(.xref) > span.pre {
227 | color: #dcddde;
228 | background-color: #00000020;
229 | }
230 |
231 | li > a.reference.internal {
232 | border-bottom: none;
233 | }
234 |
235 | li > a.reference.internal:hover {
236 | text-decoration: underline;
237 | }
238 |
239 | code.xref.py.docutils.literal.notranslate {
240 | background: transparent;
241 | }
--------------------------------------------------------------------------------
/anvil/empty_section.py:
--------------------------------------------------------------------------------
1 | from typing import List, Tuple
2 | from . import Block
3 | from .errors import OutOfBoundsCoordinates
4 | from nbt import nbt
5 | from struct import Struct
6 | import array
7 |
8 | # dirty mixin to change q to Q
9 | def _update_fmt(self, length):
10 | self.fmt = Struct(f'>{length}Q')
11 | nbt.TAG_Long_Array.update_fmt = _update_fmt
12 |
13 | def bin_append(a, b, length=None):
14 | length = length or b.bit_length()
15 | return (a << length) | b
16 |
17 | class EmptySection:
18 | """
19 | Used for making own sections.
20 |
21 | This is where the blocks are actually stored, in a 16³ sized array.
22 | To save up some space, ``None`` is used instead of the air block object,
23 | and will be replaced with ``self.air`` when needed
24 |
25 | Attributes
26 | ----------
27 | y: :class:`int`
28 | Section's Y index
29 | blocks: List[:class:`Block`]
30 | 1D list of blocks
31 | air: :class:`Block`
32 | An air block
33 | """
34 | __slots__ = ('y', 'blocks', 'air')
35 | def __init__(self, y: int):
36 | self.y = y
37 | # None is the same as an air block
38 | self.blocks: List[Block] = [None] * 4096
39 | # Block that will be used when None
40 | self.air = Block('minecraft', 'air')
41 |
42 | @staticmethod
43 | def inside(x: int, y: int, z: int) -> bool:
44 | """
45 | Check if X Y and Z are in range of 0-15
46 |
47 | Parameters
48 | ----------
49 | int x, y, z
50 | Coordinates
51 | """
52 | return x in range(16) and y in range(16) and z in range(16)
53 |
54 | def set_block(self, block: Block, x: int, y: int, z: int):
55 | """
56 | Sets the block at given coordinates
57 |
58 | Parameters
59 | ----------
60 | block
61 | Block to set
62 | int x, y, z
63 | Coordinates
64 |
65 | Raises
66 | ------
67 | anvil.OutOfBoundsCoordinates
68 | If coordinates are not in range of 0-15
69 | """
70 | if not self.inside(x, y, z):
71 | raise OutOfBoundsCoordinates('X Y and Z must be in range of 0-15')
72 | index = y * 256 + z * 16 + x
73 | self.blocks[index] = block
74 |
75 | def get_block(self, x: int, y: int, z: int) -> Block:
76 | """
77 | Gets the block at given coordinates.
78 |
79 | Parameters
80 | ----------
81 | int x, y, z
82 | Coordinates
83 |
84 | Raises
85 | ------
86 | anvil.OutOfBoundsCoordinates
87 | If coordinates are not in range of 0-15
88 | """
89 | if not self.inside(x, y, z):
90 | raise OutOfBoundsCoordinates('X Y and Z must be in range of 0-15')
91 | index = y * 256 + z * 16 + x
92 | return self.blocks[index] or self.air
93 |
94 | def palette(self) -> Tuple[Block]:
95 | """
96 | Generates and returns a tuple of all the different blocks in the section
97 | The order can change as it uses sets, but should be fine when saving since
98 | it's only called once.
99 | """
100 | palette = set(self.blocks)
101 | if None in palette:
102 | palette.remove(None)
103 | palette.add(self.air)
104 | return tuple(palette)
105 |
106 | def blockstates(self, palette: Tuple[Block]=None) -> array.array:
107 | """
108 | Returns a list of each block's index in the palette.
109 |
110 | This is used in the BlockStates tag of the section.
111 |
112 | Parameters
113 | ----------
114 | palette
115 | Section's palette. If not given will generate one.
116 | """
117 | palette = palette or self.palette()
118 | bits = max((len(palette) - 1).bit_length(), 4)
119 | states = array.array('Q')
120 | current = 0
121 | current_len = 0
122 | for block in self.blocks:
123 | if block is None:
124 | index = palette.index(self.air)
125 | else:
126 | index = palette.index(block)
127 | # If it's more than 64 bits then add to list and start over
128 | # with the remaining bits from last one
129 | if current_len + bits > 64:
130 | leftover = 64 - current_len
131 | states.append(bin_append(index & ((1 << leftover) - 1), current, length=current_len))
132 | current = index >> leftover
133 | current_len = bits - leftover
134 | else:
135 | current = bin_append(index, current, length=current_len)
136 | current_len += bits
137 | states.append(current)
138 | return states
139 |
140 | def save(self) -> nbt.TAG_Compound:
141 | """
142 | Saves the section to a TAG_Compound and is used inside the chunk tag
143 | This is missing the SkyLight tag, but minecraft still accepts it anyway
144 | """
145 | root = nbt.TAG_Compound()
146 | root.tags.append(nbt.TAG_Byte(name='Y', value=self.y))
147 |
148 | palette = self.palette()
149 | nbt_pal = nbt.TAG_List(name='Palette', type=nbt.TAG_Compound)
150 | for block in palette:
151 | tag = nbt.TAG_Compound()
152 | tag.tags.append(nbt.TAG_String(name='Name', value=block.name()))
153 | if block.properties:
154 | properties = nbt.TAG_Compound()
155 | properties.name = 'Properties'
156 | for key, value in block.properties.items():
157 | if isinstance(value, str):
158 | properties.tags.append(nbt.TAG_String(name=key, value=value))
159 | elif isinstance(value, bool):
160 | # booleans are a string saved as either 'true' or 'false'
161 | properties.tags.append(nbt.TAG_String(name=key, value=str(value).lower()))
162 | elif isinstance(value, int):
163 | # ints also seem to be saved as a string
164 | properties.tags.append(nbt.TAG_String(name=key, value=str(value)))
165 | else:
166 | # assume its a nbt tag and just append it
167 | properties.tags.append(value)
168 | tag.tags.append(properties)
169 | nbt_pal.tags.append(tag)
170 | root.tags.append(nbt_pal)
171 |
172 | states = self.blockstates(palette=palette)
173 | bstates = nbt.TAG_Long_Array(name='BlockStates')
174 | bstates.value = states
175 | root.tags.append(bstates)
176 |
177 | return root
178 |
--------------------------------------------------------------------------------
/anvil/empty_chunk.py:
--------------------------------------------------------------------------------
1 | from typing import List
2 | from .block import Block
3 | from .biome import Biome
4 | from .empty_section import EmptySection
5 | from .errors import OutOfBoundsCoordinates, EmptySectionAlreadyExists
6 | from nbt import nbt
7 | from .legacy import LEGACY_BIOMES_ID_MAP
8 |
9 |
10 | def _get_legacy_biome_id(biome: Biome) -> int:
11 | for k, v in LEGACY_BIOMES_ID_MAP.items():
12 | if v == biome.id:
13 | return k
14 | raise ValueError(f'Biome id "{biome.id}" has no legacy equivalent')
15 |
16 |
17 | class EmptyChunk:
18 | """
19 | Used for making own chunks
20 |
21 | Attributes
22 | ----------
23 | x: :class:`int`
24 | Chunk's X position
25 | z: :class:`int`
26 | Chunk's Z position
27 | sections: List[:class:`anvil.EmptySection`]
28 | List of all the sections in this chunk
29 | version: :class:`int`
30 | Chunk's DataVersion
31 | """
32 | __slots__ = ('x', 'z', 'sections', 'biomes', 'version')
33 | def __init__(self, x: int, z: int):
34 | self.x = x
35 | self.z = z
36 | self.sections: List[EmptySection] = [None]*16
37 | self.biomes: List[Biome] = [Biome('ocean')]*16*16
38 | self.version = 1976
39 |
40 | def add_section(self, section: EmptySection, replace: bool = True):
41 | """
42 | Adds a section to the chunk
43 |
44 | Parameters
45 | ----------
46 | section
47 | Section to add
48 | replace
49 | Whether to replace section if one at same Y already exists
50 |
51 | Raises
52 | ------
53 | anvil.EmptySectionAlreadyExists
54 | If ``replace`` is ``False`` and section with same Y already exists in this chunk
55 | """
56 | if self.sections[section.y] and not replace:
57 | raise EmptySectionAlreadyExists(f'EmptySection (Y={section.y}) already exists in this chunk')
58 | self.sections[section.y] = section
59 |
60 | def get_block(self, x: int, y: int, z: int) -> Block:
61 | """
62 | Gets the block at given coordinates
63 |
64 | Parameters
65 | ----------
66 | int x, z
67 | In range of 0 to 15
68 | y
69 | In range of 0 to 255
70 |
71 | Raises
72 | ------
73 | anvil.OutOfBoundCoordidnates
74 | If X, Y or Z are not in the proper range
75 |
76 | Returns
77 | -------
78 | block : :class:`anvil.Block` or None
79 | Returns ``None`` if the section is empty, meaning the block
80 | is most likely an air block.
81 | """
82 | if x not in range(16):
83 | raise OutOfBoundsCoordinates(f'X ({x!r}) must be in range of 0 to 15')
84 | if z not in range(16):
85 | raise OutOfBoundsCoordinates(f'Z ({z!r}) must be in range of 0 to 15')
86 | if y not in range(256):
87 | raise OutOfBoundsCoordinates(f'Y ({y!r}) must be in range of 0 to 255')
88 | section = self.sections[y // 16]
89 | if section is None:
90 | return
91 | return section.get_block(x, y % 16, z)
92 |
93 | def set_block(self, block: Block, x: int, y: int, z: int):
94 | """
95 | Sets block at given coordinates
96 |
97 | Parameters
98 | ----------
99 | int x, z
100 | In range of 0 to 15
101 | y
102 | In range of 0 to 255
103 |
104 | Raises
105 | ------
106 | anvil.OutOfBoundCoordidnates
107 | If X, Y or Z are not in the proper range
108 | """
109 | if x not in range(16):
110 | raise OutOfBoundsCoordinates(f'X ({x!r}) must be in range of 0 to 15')
111 | if z not in range(16):
112 | raise OutOfBoundsCoordinates(f'Z ({z!r}) must be in range of 0 to 15')
113 | if y not in range(256):
114 | raise OutOfBoundsCoordinates(f'Y ({y!r}) must be in range of 0 to 255')
115 | section = self.sections[y // 16]
116 | if section is None:
117 | section = EmptySection(y // 16)
118 | self.add_section(section)
119 | section.set_block(block, x, y % 16, z)
120 |
121 | def set_biome(self, biome: Biome, x: int, z: int):
122 | """
123 | Sets biome at given coordinates
124 |
125 | Parameters
126 | ----------
127 | int x, z
128 | In range of 0 to 15
129 |
130 | Raises
131 | ------
132 | anvil.OutOfBoundCoordidnates
133 | If X or Z are not in the proper range
134 |
135 | """
136 | if x not in range(16):
137 | raise OutOfBoundsCoordinates(f'X ({x!r}) must be in range of 0 to 15')
138 | if z not in range(16):
139 | raise OutOfBoundsCoordinates(f'Z ({z!r}) must be in range of 0 to 15')
140 |
141 | index = z * 16 + x
142 | self.biomes[index] = biome
143 |
144 | def save(self) -> nbt.NBTFile:
145 | """
146 | Saves the chunk data to a :class:`NBTFile`
147 |
148 | Notes
149 | -----
150 | Does not contain most data a regular chunk would have,
151 | but minecraft stills accept it.
152 | """
153 | root = nbt.NBTFile()
154 | root.tags.append(nbt.TAG_Int(name='DataVersion',value=self.version))
155 | level = nbt.TAG_Compound()
156 | # Needs to be in a separate line because it just gets
157 | # ignored if you pass it as a kwarg in the constructor
158 | level.name = 'Level'
159 | level.tags.extend([
160 | nbt.TAG_List(name='Entities', type=nbt.TAG_Compound),
161 | nbt.TAG_List(name='TileEntities', type=nbt.TAG_Compound),
162 | nbt.TAG_List(name='LiquidTicks', type=nbt.TAG_Compound),
163 | nbt.TAG_Int(name='xPos', value=self.x),
164 | nbt.TAG_Int(name='zPos', value=self.z),
165 | nbt.TAG_Long(name='LastUpdate', value=0),
166 | nbt.TAG_Long(name='InhabitedTime', value=0),
167 | nbt.TAG_Byte(name='isLightOn', value=1),
168 | nbt.TAG_String(name='Status', value='full')
169 | ])
170 | sections = nbt.TAG_List(name='Sections', type=nbt.TAG_Compound)
171 | biomes = nbt.TAG_Int_Array(name='Biomes')
172 |
173 | biomes.value = [_get_legacy_biome_id(biome) for biome in self.biomes]
174 | for s in self.sections:
175 | if s:
176 | p = s.palette()
177 | # Minecraft does not save sections that are just air
178 | # So we can just skip them
179 | if len(p) == 1 and p[0].name() == 'minecraft:air':
180 | continue
181 | sections.tags.append(s.save())
182 | level.tags.append(sections)
183 | level.tags.append(biomes)
184 | root.tags.append(level)
185 | return root
186 |
--------------------------------------------------------------------------------
/anvil/empty_region.py:
--------------------------------------------------------------------------------
1 | from typing import Union, List, BinaryIO
2 | from .empty_chunk import EmptyChunk
3 | from .chunk import Chunk
4 | from .empty_section import EmptySection
5 | from .block import Block
6 | from .biome import Biome
7 | from .errors import OutOfBoundsCoordinates
8 | from .versions import VERSION_21w43a
9 | from io import BytesIO
10 | from nbt import nbt
11 | import zlib
12 | import math
13 |
14 | def from_inclusive(a, b):
15 | """Returns a range from a to b, including both endpoints"""
16 | c = int(b > a)*2-1
17 | return range(a, b+c, c)
18 |
19 | class EmptyRegion:
20 | """
21 | Used for making own regions
22 |
23 | Attributes
24 | ----------
25 | chunks: List[:class:`anvil.EmptyChunk`]
26 | List of chunks in this region
27 | x: :class:`int`
28 | z: :class:`int`
29 | """
30 | __slots__ = ('chunks', 'x', 'z')
31 | def __init__(self, x: int, z: int):
32 | # Create a 1d list for the 32x32 chunks
33 | self.chunks: List[EmptyChunk] = [None] * 1024
34 | self.x = x
35 | self.z = z
36 |
37 | def inside(self, x: int, y: int, z: int, chunk: bool=False) -> bool:
38 | """
39 | Returns if the given coordinates are inside this region
40 |
41 | Parameters
42 | ----------
43 | int x, y, z
44 | Coordinates
45 | chunk
46 | Whether coordinates are global or chunk coordinates
47 | """
48 | factor = 32 if chunk else 512
49 | rx = x // factor
50 | rz = z // factor
51 | return not (rx != self.x or rz != self.z or y not in range(256))
52 |
53 | def get_chunk(self, x: int, z: int) -> EmptyChunk:
54 | """
55 | Returns the chunk at given chunk coordinates
56 |
57 | Parameters
58 | ----------
59 | int x, z
60 | Chunk's coordinates
61 |
62 | Raises
63 | ------
64 | anvil.OutOfBoundCoordidnates
65 | If the chunk (x, z) is not inside this region
66 |
67 | :rtype: :class:`anvil.EmptyChunk`
68 | """
69 | if not self.inside(x, 0, z, chunk=True):
70 | raise OutOfBoundsCoordinates(f'Chunk ({x}, {z}) is not inside this region')
71 | return self.chunks[z % 32 * 32 + x % 32]
72 |
73 | def add_chunk(self, chunk: EmptyChunk):
74 | """
75 | Adds given chunk to this region.
76 | Will overwrite if a chunk already exists in this location
77 |
78 | Parameters
79 | ----------
80 | chunk: :class:`EmptyChunk`
81 |
82 | Raises
83 | ------
84 | anvil.OutOfBoundCoordidnates
85 | If the chunk (x, z) is not inside this region
86 | """
87 | if not self.inside(chunk.x, 0, chunk.z, chunk=True):
88 | raise OutOfBoundsCoordinates(f'Chunk ({chunk.x}, {chunk.z}) is not inside this region')
89 | self.chunks[chunk.z % 32 * 32 + chunk.x % 32] = chunk
90 |
91 | def add_section(self, section: EmptySection, x: int, z: int, replace: bool=True):
92 | """
93 | Adds section to chunk at (x, z).
94 | Same as ``EmptyChunk.add_section(section)``
95 |
96 | Parameters
97 | ----------
98 | section: :class:`EmptySection`
99 | Section to add
100 | int x, z
101 | Chunk's coordinate
102 | replace
103 | Whether to replace section if it already exists in the chunk
104 |
105 | Raises
106 | ------
107 | anvil.OutOfBoundsCoordinates
108 | If the chunk (x, z) is not inside this region
109 | """
110 | if not self.inside(x, 0, z, chunk=True):
111 | raise OutOfBoundsCoordinates(f'Chunk ({x}, {z}) is not inside this region')
112 | chunk = self.chunks[z % 32 * 32 + x % 32]
113 | if chunk is None:
114 | chunk = EmptyChunk(x, z)
115 | self.add_chunk(chunk)
116 | chunk.add_section(section, replace)
117 |
118 | def set_block(self, block: Block, x: int, y: int, z: int):
119 | """
120 | Sets block at given coordinates.
121 | New chunk is made if it doesn't exist.
122 |
123 | Parameters
124 | ----------
125 | block: :class:`Block`
126 | Block to place
127 | int x, y, z
128 | Coordinates
129 |
130 | Raises
131 | ------
132 | anvil.OutOfBoundsCoordinates
133 | If the block (x, y, z) is not inside this region
134 | """
135 | if not self.inside(x, y, z):
136 | raise OutOfBoundsCoordinates(f'Block ({x}, {y}, {z}) is not inside this region')
137 | cx = x // 16
138 | cz = z // 16
139 | chunk = self.get_chunk(cx, cz)
140 | if chunk is None:
141 | chunk = EmptyChunk(cx, cz)
142 | self.add_chunk(chunk)
143 | chunk.set_block(block, x % 16, y, z % 16)
144 |
145 | def set_biome(self, biome: Biome, x: int, z: int):
146 | """
147 | Sets biome at given coordinates.
148 | New chunk is made if it doesn't exist.
149 |
150 | Parameters
151 | ----------
152 | biome: :class:`Biome`
153 | Biome to place
154 | int x, z
155 | Coordinates
156 |
157 | Raises
158 | ------
159 | anvil.OutOfBoundsCoordinates
160 | If the biome (x, z) is not inside this region
161 | """
162 | if not self.inside(x, 0, z):
163 | raise OutOfBoundsCoordinates(f'Biome ({x}, {z}) is not inside this region')
164 | cx = x // 16
165 | cz = z // 16
166 | chunk = self.get_chunk(cx, cz)
167 | if chunk is None:
168 | chunk = EmptyChunk(cx, cz)
169 | self.add_chunk(chunk)
170 | chunk.set_biome(biome, x % 16, z % 16)
171 |
172 | def set_if_inside(self, block: Block, x: int, y: int, z: int):
173 | """
174 | Helper function that only sets
175 | the block if ``self.inside(x, y, z)`` is true
176 |
177 | Parameters
178 | ----------
179 | block: :class:`Block`
180 | Block to place
181 | int x, y, z
182 | Coordinates
183 | """
184 | if self.inside(x, y, z):
185 | self.set_block(block, x, y, z)
186 |
187 | def set_biome_if_inside(self, biome: Biome, x: int, z: int):
188 | """
189 | Helper function that only sets
190 | the biome if ``self.inside(x, 0, z)`` is true
191 |
192 | Parameters
193 | ----------
194 | biome: :class:`Biome`
195 | Biome to place
196 | int x, z
197 | Coordinates
198 | """
199 | if self.inside(x, 0, z):
200 | self.set_biome(biome, x, z)
201 |
202 | def fill(self, block: Block, x1: int, y1: int, z1: int, x2: int, y2: int, z2: int, ignore_outside: bool=False):
203 | """
204 | Fills in blocks from
205 | ``(x1, y1, z1)`` to ``(x2, y2, z2)``
206 | in a rectangle.
207 |
208 | Parameters
209 | ----------
210 | block: :class:`Block`
211 | int x1, y1, z1
212 | Coordinates
213 | int x2, y2, z2
214 | Coordinates
215 | ignore_outside
216 | Whether to ignore if coordinates are outside the region
217 |
218 | Raises
219 | ------
220 | anvil.OutOfBoundsCoordinates
221 | If any of the coordinates are outside the region
222 | """
223 | if not ignore_outside:
224 | if not self.inside(x1, y1, z1):
225 | raise OutOfBoundsCoordinates(f'First coords ({x1}, {y1}, {z1}) is not inside this region')
226 | if not self.inside(x2, y2, z2):
227 | raise OutOfBoundsCoordinates(f'Second coords ({x}, {y}, {z}) is not inside this region')
228 |
229 | for y in from_inclusive(y1, y2):
230 | for z in from_inclusive(z1, z2):
231 | for x in from_inclusive(x1, x2):
232 | if ignore_outside:
233 | self.set_if_inside(block, x, y, z)
234 | else:
235 | self.set_block(block, x, y, z)
236 |
237 | def fill_biome(self, biome: Biome, x1: int, z1: int, x2: int, z2: int, ignore_outside: bool=False):
238 | """
239 | Fills in biomes from
240 | ``(x1, z1)`` to ``(x2, z2)``
241 | in a rectangle.
242 |
243 | Parameters
244 | ----------
245 | biome: :class:`Biome`
246 | int x1, z1
247 | Coordinates
248 | int x2, z2
249 | Coordinates
250 | ignore_outside
251 | Whether to ignore if coordinates are outside the region
252 |
253 | Raises
254 | ------
255 | anvil.OutOfBoundsCoordinates
256 | If any of the coordinates are outside the region
257 | """
258 | if not ignore_outside:
259 | if not self.inside(x1, 0, z1):
260 | raise OutOfBoundsCoordinates(f'First coords ({x1}, {z1}) is not inside this region')
261 | if not self.inside(x2, 0, z2):
262 | raise OutOfBoundsCoordinates(f'Second coords ({x2}, {z2}) is not inside this region')
263 |
264 | for z in from_inclusive(z1, z2):
265 | for x in from_inclusive(x1, x2):
266 | if ignore_outside:
267 | self.set_biome_if_inside(biome, x, z)
268 | else:
269 | self.set_biome(biome, x, z)
270 |
271 | def save(self, file: Union[str, BinaryIO]=None) -> bytes:
272 | """
273 | Returns the region as bytes with
274 | the anvil file format structure,
275 | aka the final ``.mca`` file.
276 |
277 | Parameters
278 | ----------
279 | file
280 | Either a path or a file object, if given region
281 | will be saved there.
282 | """
283 | # Store all the chunks data as zlib compressed nbt data
284 | chunks_data = []
285 | for chunk in self.chunks:
286 | if chunk is None:
287 | chunks_data.append(None)
288 | continue
289 | chunk_data = BytesIO()
290 | if isinstance(chunk, Chunk):
291 | nbt_data = nbt.NBTFile()
292 | nbt_data.tags.append(nbt.TAG_Int(name='DataVersion', value=chunk.version))
293 |
294 | if chunk.version >= VERSION_21w43a:
295 | for tag in chunk.data.tags:
296 | nbt_data.tags.append(tag)
297 | else:
298 | nbt_data.tags.append(chunk.data)
299 | else:
300 | nbt_data = chunk.save()
301 | nbt_data.write_file(buffer=chunk_data)
302 | chunk_data.seek(0)
303 | chunk_data = zlib.compress(chunk_data.read())
304 | chunks_data.append(chunk_data)
305 |
306 | # This is what is added after the location and timestamp header
307 | chunks_bytes = bytes()
308 | offsets = []
309 | for chunk in chunks_data:
310 | if chunk is None:
311 | offsets.append(None)
312 | continue
313 | # 4 bytes are for length, b'\x02' is the compression type which is 2 since its using zlib
314 | to_add = (len(chunk)+1).to_bytes(4, 'big') + b'\x02' + chunk
315 |
316 | # offset in 4KiB sectors
317 | sector_offset = len(chunks_bytes) // 4096
318 | sector_count = math.ceil(len(to_add) / 4096)
319 | offsets.append((sector_offset, sector_count))
320 |
321 | # Padding to be a multiple of 4KiB long
322 | to_add += bytes(4096 - (len(to_add) % 4096))
323 | chunks_bytes += to_add
324 |
325 | locations_header = bytes()
326 | for offset in offsets:
327 | # None means the chunk is not an actual chunk in the region
328 | # and will be 4 null bytes, which represents non-generated chunks to minecraft
329 | if offset is None:
330 | locations_header += bytes(4)
331 | else:
332 | # offset is (sector offset, sector count)
333 | locations_header += (offset[0] + 2).to_bytes(3, 'big') + offset[1].to_bytes(1, 'big')
334 |
335 | # Set them all as 0
336 | timestamps_header = bytes(4096)
337 |
338 | final = locations_header + timestamps_header + chunks_bytes
339 |
340 | # Pad file to be a multiple of 4KiB in size
341 | # as Minecraft only accepts region files that are like that
342 | final += bytes(4096 - (len(final) % 4096))
343 | assert len(final) % 4096 == 0 # just in case
344 |
345 | # Save to a file if it was given
346 | if file:
347 | if isinstance(file, str):
348 | with open(file, 'wb') as f:
349 | f.write(final)
350 | else:
351 | file.write(final)
352 | return final
353 |
--------------------------------------------------------------------------------
/anvil/chunk.py:
--------------------------------------------------------------------------------
1 | from typing import Union, Tuple, Generator, Optional
2 | from nbt import nbt
3 | from .biome import Biome
4 | from .block import Block, OldBlock
5 | from .region import Region
6 | from .errors import OutOfBoundsCoordinates, ChunkNotFound
7 | from .versions import VERSION_21w43a, VERSION_20w17a, VERSION_19w36a, VERSION_17w47a, VERSION_PRE_15w32a
8 |
9 |
10 | def bin_append(a, b, length=None):
11 | """
12 | Appends number a to the left of b
13 | bin_append(0b1, 0b10) = 0b110
14 | """
15 | length = length or b.bit_length()
16 | return (a << length) | b
17 |
18 |
19 | def nibble(byte_array, index):
20 | value = byte_array[index // 2]
21 | if index % 2:
22 | return value >> 4
23 | else:
24 | return value & 0b1111
25 |
26 |
27 | def _palette_from_section(section: nbt.TAG_Compound) -> nbt.TAG_List:
28 | if 'block_states' in section:
29 | return section["block_states"]["palette"]
30 | else:
31 | return section["Palette"]
32 |
33 |
34 | def _states_from_section(section: nbt.TAG_Compound) -> list:
35 | # BlockStates is an array of 64 bit numbers
36 | # that holds the blocks index on the palette list
37 | if 'block_states' in section:
38 | states = section['block_states']['data']
39 | else:
40 | states = section['BlockStates']
41 |
42 | # makes sure the number is unsigned
43 | # by adding 2^64
44 | # could also use ctypes.c_ulonglong(n).value but that'd require an extra import
45 |
46 | return [state if state >= 0 else states + 2 ** 64
47 | for state in states.value]
48 |
49 |
50 | def _section_height_range(version: Optional[int]) -> range:
51 | if version > VERSION_17w47a:
52 | return range(-4, 20)
53 | else:
54 | return range(16)
55 |
56 |
57 | class Chunk:
58 | """
59 | Represents a chunk from a ``.mca`` file.
60 |
61 | Note that this is read only.
62 |
63 | Attributes
64 | ----------
65 | x: :class:`int`
66 | Chunk's X position
67 | z: :class:`int`
68 | Chunk's Z position
69 | version: :class:`int`
70 | Version of the chunk NBT structure
71 | data: :class:`nbt.TAG_Compound`
72 | Raw NBT data of the chunk
73 | tile_entities: :class:`nbt.TAG_Compound`
74 | ``self.data['TileEntities']`` as an attribute for easier use
75 | """
76 |
77 | __slots__ = ("version", "data", "x", "z", "tile_entities")
78 |
79 | def __init__(self, nbt_data: nbt.NBTFile):
80 | try:
81 | self.version = nbt_data["DataVersion"].value
82 | except KeyError:
83 | # Version is pre-1.9 snapshot 15w32a, so world does not have a Data Version.
84 | # See https://minecraft.wiki/w/Data_version
85 | self.version = VERSION_PRE_15w32a
86 |
87 | if self.version >= VERSION_21w43a:
88 | self.data = nbt_data
89 | self.tile_entities = self.data["block_entities"]
90 | else:
91 | self.data = nbt_data["Level"]
92 | self.tile_entities = self.data["TileEntities"]
93 | self.x = self.data["xPos"].value
94 | self.z = self.data["zPos"].value
95 |
96 | def get_section(self, y: int) -> nbt.TAG_Compound:
97 | """
98 | Returns the section at given y index
99 | can also return nothing if section is missing, aka it's empty
100 |
101 | Parameters
102 | ----------
103 | y
104 | Section Y index
105 |
106 | Raises
107 | ------
108 | anvil.OutOfBoundsCoordinates
109 | If Y is not in range of 0 to 15
110 | """
111 | section_range = _section_height_range(self.version)
112 | if y not in section_range:
113 | raise OutOfBoundsCoordinates(f"Y ({y!r}) must be in range of "
114 | f"{section_range.start} to {section_range.stop}")
115 |
116 | if 'sections' in self.data:
117 | sections = self.data["sections"]
118 | else:
119 | try:
120 | sections = self.data["Sections"]
121 | except KeyError:
122 | return None
123 |
124 | for section in sections:
125 | if section["Y"].value == y:
126 | return section
127 |
128 | def get_palette(self, section: Union[int, nbt.TAG_Compound]) -> Tuple[Block]:
129 | """
130 | Returns the block palette for given section
131 |
132 | Parameters
133 | ----------
134 | section
135 | Either a section NBT tag or an index
136 |
137 |
138 | :rtype: Tuple[:class:`anvil.Block`]
139 | """
140 | if isinstance(section, int):
141 | section = self.get_section(section)
142 | if section is None:
143 | return
144 | palette = _palette_from_section(section)
145 | return tuple(Block.from_palette(i) for i in palette)
146 |
147 | def get_biome(self, x: int, y: int, z: int) -> Biome:
148 | """
149 | Returns the biome in the given coordinates
150 |
151 | Parameters
152 | ----------
153 | int x, y, z
154 | Biome's coordinates in the chunk
155 |
156 | Raises
157 | ------
158 | anvil.OutOfBoundCoordidnates
159 | If X, Y or Z are not in the proper range
160 |
161 | :rtype: :class:`anvil.Biome`
162 | """
163 | section_range = _section_height_range(self.version)
164 | if x not in range(16):
165 | raise OutOfBoundsCoordinates(f"X ({x!r}) must be in range of 0 to 15")
166 | if z not in range(16):
167 | raise OutOfBoundsCoordinates(f"Z ({z!r}) must be in range of 0 to 15")
168 | if y // 16 not in section_range:
169 | raise OutOfBoundsCoordinates(f"Y ({y!r}) must be in range of "
170 | f"{section_range.start * 16} to {section_range.stop * 16 - 1}")
171 |
172 | if 'Biomes' not in self.data:
173 | # Each biome index refers to a 4x4x4 volumes here so we do integer division by 4
174 | section = self.get_section(y // 16)
175 | biomes = section['biomes']
176 | biomes_palette = biomes['palette']
177 | if 'data' in biomes:
178 | biomes = biomes['data']
179 | else:
180 | # When there is only one biome in the section of the palette 'data'
181 | # is not present
182 | return Biome.from_name(biomes_palette[0].value)
183 |
184 |
185 | index = ((y % 16 // 4) * 4 * 4) + (z // 4) * 4 + (x // 4)
186 | bits = (len(biomes_palette) - 1).bit_length()
187 | state = index * bits // 64
188 | data = biomes[state]
189 |
190 | # shift the number to the right to remove the left over bits
191 | # and shift so the i'th biome is the first one
192 | shifted_data = data >> ((bits * index) % 64)
193 |
194 | # if there aren't enough bits it means the rest are in the next number
195 | if 64 - ((bits * index) % 64) < bits:
196 | data = biomes[state + 1]
197 |
198 | # get how many bits are from a palette index of the next biome
199 | leftover = (bits - ((state + 1) * 64 % bits)) % bits
200 |
201 | # Make sure to keep the length of the bits in the first state
202 | # Example: bits is 5, and leftover is 3
203 | # Next state Current state (already shifted)
204 | # 0b101010110101101010010 0b01
205 | # will result in bin_append(0b010, 0b01, 2) = 0b01001
206 | shifted_data = bin_append(
207 | data & 2**leftover - 1, shifted_data, bits - leftover
208 | )
209 |
210 | palette_id = shifted_data & 2**bits - 1
211 | return Biome.from_name(biomes_palette[palette_id].value)
212 |
213 | else:
214 | biomes = self.data["Biomes"]
215 | if self.version < VERSION_19w36a:
216 | # Each biome index refers to a column stored Z then X.
217 | index = z * 16 + x
218 | else:
219 | # https://minecraft.wiki/w/Java_Edition_19w36a
220 | # Get index on the biome list with the order YZX
221 | # Each biome index refers to a 4x4 areas here so we do integer division by 4
222 | index = (y // 4) * 4 * 4 + (z // 4) * 4 + (x // 4)
223 | biome_id = biomes[index]
224 | return Biome.from_numeric_id(biome_id)
225 |
226 | def get_block(
227 | self,
228 | x: int,
229 | y: int,
230 | z: int,
231 | section: Union[int, nbt.TAG_Compound] = None,
232 | force_new: bool = False,
233 | ) -> Union[Block, OldBlock]:
234 | """
235 | Returns the block in the given coordinates
236 |
237 | Parameters
238 | ----------
239 | int x, y, z
240 | Block's coordinates in the chunk
241 | section : int
242 | Either a section NBT tag or an index. If no section is given,
243 | assume Y is global and use it for getting the section.
244 | force_new
245 | Always returns an instance of Block if True, otherwise returns type OldBlock for pre-1.13 versions.
246 | Defaults to False
247 |
248 | Raises
249 | ------
250 | anvil.OutOfBoundCoordidnates
251 | If X, Y or Z are not in the proper range
252 |
253 | :rtype: :class:`anvil.Block`
254 | """
255 | if x not in range(16):
256 | raise OutOfBoundsCoordinates(f"X ({x!r}) must be in range of 0 to 15")
257 | if z not in range(16):
258 | raise OutOfBoundsCoordinates(f"Z ({z!r}) must be in range of 0 to 15")
259 | section_range = _section_height_range(self.version)
260 | if y // 16 not in section_range:
261 | raise OutOfBoundsCoordinates(f"Y ({y!r}) must be in range of "
262 | f"{section_range.start * 16} to {section_range.stop * 16 - 1}")
263 |
264 | if section is None:
265 | section = self.get_section(y // 16)
266 | # global Y to section Y
267 | y %= 16
268 |
269 | if self.version < VERSION_17w47a:
270 | # Explained in depth here https://minecraft.wiki/w/index.php?title=Chunk_format&oldid=1153403#Block_format
271 |
272 | if section is None or "Blocks" not in section:
273 | if force_new:
274 | return Block.from_name("minecraft:air")
275 | else:
276 | return OldBlock(0)
277 |
278 | index = y * 16 * 16 + z * 16 + x
279 |
280 | block_id = section["Blocks"][index]
281 | if "Add" in section:
282 | block_id += nibble(section["Add"], index) << 8
283 |
284 | block_data = nibble(section["Data"], index)
285 |
286 | block = OldBlock(block_id, block_data)
287 | if force_new:
288 | return block.convert()
289 | else:
290 | return block
291 |
292 | # If its an empty section its most likely an air block
293 | if section is None:
294 | return Block.from_name("minecraft:air")
295 | try:
296 | states = _states_from_section(section)
297 | except KeyError:
298 | return Block.from_name("minecraft:air")
299 |
300 | # Number of bits each block is on BlockStates
301 | # Cannot be lower than 4
302 | palette = _palette_from_section(section)
303 |
304 | bits = max((len(palette) - 1).bit_length(), 4)
305 |
306 | # Get index on the block list with the order YZX
307 | index = y * 16 * 16 + z * 16 + x
308 | # in 20w17a and newer blocks cannot occupy more than one element on the BlockStates array
309 | stretches = self.version < VERSION_20w17a
310 |
311 | # get location in the BlockStates array via the index
312 | if stretches:
313 | state = index * bits // 64
314 | else:
315 | state = index // (64 // bits)
316 |
317 | data = states[state]
318 |
319 | if stretches:
320 | # shift the number to the right to remove the left over bits
321 | # and shift so the i'th block is the first one
322 | shifted_data = data >> ((bits * index) % 64)
323 | else:
324 | shifted_data = data >> (index % (64 // bits) * bits)
325 |
326 | # if there aren't enough bits it means the rest are in the next number
327 | if stretches and 64 - ((bits * index) % 64) < bits:
328 | data = states[state + 1]
329 |
330 | # get how many bits are from a palette index of the next block
331 | leftover = (bits - ((state + 1) * 64 % bits)) % bits
332 |
333 | # Make sure to keep the length of the bits in the first state
334 | # Example: bits is 5, and leftover is 3
335 | # Next state Current state (already shifted)
336 | # 0b101010110101101010010 0b01
337 | # will result in bin_append(0b010, 0b01, 2) = 0b01001
338 | shifted_data = bin_append(
339 | data & 2**leftover - 1, shifted_data, bits - leftover
340 | )
341 |
342 | # get `bits` least significant bits
343 | # which are the palette index
344 | palette_id = shifted_data & 2**bits - 1
345 | return Block.from_palette(palette[palette_id])
346 |
347 | def stream_blocks(
348 | self,
349 | index: int = 0,
350 | section: Union[int, nbt.TAG_Compound] = None,
351 | force_new: bool = False,
352 | ) -> Generator[Block, None, None]:
353 | """
354 | Returns a generator for all the blocks in given section
355 |
356 | Parameters
357 | ----------
358 | index
359 | At what block to start from.
360 |
361 | To get an index from (x, y, z), simply do:
362 |
363 | ``y * 256 + z * 16 + x``
364 | section
365 | Either a Y index or a section NBT tag.
366 | force_new
367 | Always returns an instance of Block if True, otherwise returns type OldBlock for pre-1.13 versions.
368 | Defaults to False
369 |
370 | Raises
371 | ------
372 | anvil.OutOfBoundCoordidnates
373 | If `section` is not in the range of 0 to 15
374 |
375 | Yields
376 | ------
377 | :class:`anvil.Block`
378 | """
379 |
380 | if isinstance(section, int):
381 | section_range = _section_height_range(self.version)
382 | if section not in section_range:
383 | raise OutOfBoundsCoordinates(f"section ({section!r}) must be in range of "
384 | f"{section_range.start} to {section_range.stop}")
385 |
386 | # For better understanding of this code, read get_block()'s source
387 |
388 | if section is None or isinstance(section, int):
389 | section = self.get_section(section or 0)
390 |
391 | if self.version < VERSION_17w47a:
392 | if section is None or "Blocks" not in section:
393 | air = Block.from_name("minecraft:air") if force_new else OldBlock(0)
394 | for _ in range(4096):
395 | yield air
396 | return
397 |
398 | while index < 4096:
399 | block_id = section["Blocks"][index]
400 | if "Add" in section:
401 | block_id += nibble(section["Add"], index) << 8
402 |
403 | block_data = nibble(section["Data"], index)
404 |
405 | block = OldBlock(block_id, block_data)
406 | if force_new:
407 | yield block.convert()
408 | else:
409 | yield block
410 |
411 | index += 1
412 | return
413 |
414 | air = Block.from_name("minecraft:air")
415 | if section is None:
416 | for _ in range(4096):
417 | yield air
418 | return
419 | try:
420 | states = _states_from_section(section)
421 | except KeyError:
422 | for _ in range(4096):
423 | yield air
424 | return
425 |
426 | palette = _palette_from_section(section)
427 | bits = max((len(palette) - 1).bit_length(), 4)
428 |
429 | stretches = self.version < VERSION_20w17a
430 |
431 | if stretches:
432 | state = index * bits // 64
433 | else:
434 | state = index // (64 // bits)
435 |
436 | data = states[state]
437 |
438 | bits_mask = 2**bits - 1
439 |
440 | if stretches:
441 | offset = (bits * index) % 64
442 | else:
443 | offset = index % (64 // bits) * bits
444 |
445 | data_len = 64 - offset
446 | data >>= offset
447 |
448 | while index < 4096:
449 | if data_len < bits:
450 | state += 1
451 | new_data = states[state]
452 |
453 | if stretches:
454 | leftover = data_len
455 | data_len += 64
456 |
457 | data = bin_append(new_data, data, leftover)
458 | else:
459 | data = new_data
460 | data_len = 64
461 |
462 | palette_id = data & bits_mask
463 | yield Block.from_palette(palette[palette_id])
464 |
465 | index += 1
466 | data >>= bits
467 | data_len -= bits
468 |
469 | def stream_chunk(
470 | self, index: int = 0, section: Union[int, nbt.TAG_Compound] = None
471 | ) -> Generator[Block, None, None]:
472 | """
473 | Returns a generator for all the blocks in the chunk
474 |
475 | This is a helper function that runs Chunk.stream_blocks from section 0 to 15
476 |
477 | Yields
478 | ------
479 | :class:`anvil.Block`
480 | """
481 | for section in _section_height_range(self.version):
482 | for block in self.stream_blocks(section=section):
483 | yield block
484 |
485 | def get_tile_entity(self, x: int, y: int, z: int) -> Optional[nbt.TAG_Compound]:
486 | """
487 | Returns the tile entity at given coordinates, or ``None`` if there isn't a tile entity
488 |
489 | To iterate through all tile entities in the chunk, use :class:`Chunk.tile_entities`
490 | """
491 | for tile_entity in self.tile_entities:
492 | t_x, t_y, t_z = [tile_entity[k].value for k in "xyz"]
493 | if x == t_x and y == t_y and z == t_z:
494 | return tile_entity
495 |
496 | @classmethod
497 | def from_region(cls, region: Union[str, Region], chunk_x: int, chunk_z: int):
498 | """
499 | Creates a new chunk from region and the chunk's X and Z
500 |
501 | Parameters
502 | ----------
503 | region
504 | Either a :class:`anvil.Region` or a region file name (like ``r.0.0.mca``)
505 |
506 | Raises
507 | ----------
508 | anvil.ChunkNotFound
509 | If a chunk is outside this region or hasn't been generated yet
510 | """
511 | if isinstance(region, str):
512 | region = Region.from_file(region)
513 | nbt_data = region.chunk_data(chunk_x, chunk_z)
514 | if nbt_data is None:
515 | raise ChunkNotFound(f"Could not find chunk ({chunk_x}, {chunk_z})")
516 | return cls(nbt_data)
517 |
--------------------------------------------------------------------------------
/anvil/legacy_blocks.json:
--------------------------------------------------------------------------------
1 | {
2 | "0:0": ["air", null],
3 | "1:0": ["stone", null],
4 | "1:1": ["granite", null],
5 | "1:2": ["polished_granite", null],
6 | "1:3": ["diorite", null],
7 | "1:4": ["polished_diorite", null],
8 | "1:5": ["andesite", null],
9 | "1:6": ["polished_andesite", null],
10 | "2:0": ["grass_block", null],
11 | "3:0": ["dirt", null],
12 | "3:1": ["coarse_dirt", null],
13 | "3:2": ["podzol", null],
14 | "4:0": ["cobblestone", null],
15 | "5:0": ["oak_planks", null],
16 | "5:1": ["spruce_planks", null],
17 | "5:2": ["birch_planks", null],
18 | "5:3": ["jungle_planks", null],
19 | "5:4": ["acacia_planks", null],
20 | "5:5": ["dark_oak_planks", null],
21 | "6:0": ["oak_sapling", null],
22 | "6:1": ["spruce_sapling", null],
23 | "6:2": ["birch_sapling", null],
24 | "6:3": ["jungle_sapling", null],
25 | "6:4": ["acacia_sapling", null],
26 | "6:5": ["dark_oak_sapling", null],
27 | "7:0": ["bedrock", null],
28 |
29 | "8:0": ["flowing_water", {"level": 0, "falling": false}],
30 | "8:1": ["flowing_water", {"level": 1, "falling": false}],
31 | "8:2": ["flowing_water", {"level": 2, "falling": false}],
32 | "8:3": ["flowing_water", {"level": 3, "falling": false}],
33 | "8:4": ["flowing_water", {"level": 4, "falling": false}],
34 | "8:5": ["flowing_water", {"level": 5, "falling": false}],
35 | "8:6": ["flowing_water", {"level": 6, "falling": false}],
36 | "8:7": ["flowing_water", {"level": 7, "falling": false}],
37 | "8:8": ["flowing_water", {"level": 0, "falling": true}],
38 | "8:9": ["flowing_water", {"level": 1, "falling": true}],
39 | "8:10": ["flowing_water", {"level": 2, "falling": true}],
40 | "8:11": ["flowing_water", {"level": 3, "falling": true}],
41 | "8:12": ["flowing_water", {"level": 4, "falling": true}],
42 | "8:13": ["flowing_water", {"level": 5, "falling": true}],
43 | "8:14": ["flowing_water", {"level": 6, "falling": true}],
44 | "8:15": ["flowing_water", {"level": 7, "falling": true}],
45 |
46 | "9:0": ["water", {"level": 0}],
47 | "9:1": ["water", {"level": 1}],
48 | "9:2": ["water", {"level": 2}],
49 | "9:3": ["water", {"level": 3}],
50 | "9:4": ["water", {"level": 4}],
51 | "9:5": ["water", {"level": 5}],
52 | "9:6": ["water", {"level": 6}],
53 | "9:7": ["water", {"level": 7}],
54 | "9:8": ["water", {"level": 8}],
55 | "9:9": ["water", {"level": 9}],
56 | "9:10": ["water", {"level": 10}],
57 | "9:11": ["water", {"level": 11}],
58 | "9:12": ["water", {"level": 12}],
59 | "9:13": ["water", {"level": 13}],
60 | "9:14": ["water", {"level": 14}],
61 | "9:15": ["water", {"level": 15}],
62 |
63 | "10:0": ["flowing_lava", {"level": 0, "falling": false}],
64 | "10:1": ["flowing_lava", {"level": 1, "falling": false}],
65 | "10:2": ["flowing_lava", {"level": 2, "falling": false}],
66 | "10:3": ["flowing_lava", {"level": 3, "falling": false}],
67 | "10:4": ["flowing_lava", {"level": 4, "falling": false}],
68 | "10:5": ["flowing_lava", {"level": 5, "falling": false}],
69 | "10:6": ["flowing_lava", {"level": 6, "falling": false}],
70 | "10:7": ["flowing_lava", {"level": 7, "falling": false}],
71 | "10:8": ["flowing_lava", {"level": 0, "falling": true}],
72 | "10:9": ["flowing_lava", {"level": 1, "falling": true}],
73 | "10:10": ["flowing_lava", {"level": 2, "falling": true}],
74 | "10:11": ["flowing_lava", {"level": 3, "falling": true}],
75 | "10:12": ["flowing_lava", {"level": 4, "falling": true}],
76 | "10:13": ["flowing_lava", {"level": 5, "falling": true}],
77 | "10:14": ["flowing_lava", {"level": 6, "falling": true}],
78 | "10:15": ["flowing_lava", {"level": 7, "falling": true}],
79 |
80 | "11:0": ["lava", {"level": 0}],
81 | "11:1": ["lava", {"level": 1}],
82 | "11:2": ["lava", {"level": 2}],
83 | "11:3": ["lava", {"level": 3}],
84 | "11:4": ["lava", {"level": 4}],
85 | "11:5": ["lava", {"level": 5}],
86 | "11:6": ["lava", {"level": 6}],
87 | "11:7": ["lava", {"level": 7}],
88 | "11:8": ["lava", {"level": 8}],
89 | "11:9": ["lava", {"level": 9}],
90 | "11:10": ["lava", {"level": 10}],
91 | "11:11": ["lava", {"level": 11}],
92 | "11:12": ["lava", {"level": 12}],
93 | "11:13": ["lava", {"level": 13}],
94 | "11:14": ["lava", {"level": 14}],
95 | "11:15": ["lava", {"level": 15}],
96 |
97 | "12:0": ["sand", null],
98 | "12:1": ["red_sand", null],
99 | "13:0": ["gravel", null],
100 | "14:0": ["gold_ore", null],
101 | "15:0": ["iron_ore", null],
102 | "16:0": ["coal_ore", null],
103 |
104 | "17:0": ["oak_log", {"axis": "y"}],
105 | "17:1": ["spruce_log", {"axis": "y"}],
106 | "17:2": ["birch_log", {"axis": "y"}],
107 | "17:3": ["jungle_log", {"axis": "y"}],
108 | "17:4": ["oak_log", {"axis": "x"}],
109 | "17:5": ["spruce_log", {"axis": "x"}],
110 | "17:6": ["birch_log", {"axis": "x"}],
111 | "17:7": ["jungle_log", {"axis": "x"}],
112 | "17:8": ["oak_log", {"axis": "z"}],
113 | "17:9": ["spruce_log", {"axis": "z"}],
114 | "17:10": ["birch_log", {"axis": "z"}],
115 | "17:11": ["jungle_log", {"axis": "z"}],
116 | "17:12": ["oak_log", null],
117 | "17:13": ["spruce_log", null],
118 | "17:14": ["birch_log", null],
119 | "17:15": ["jungle_log", null],
120 |
121 | "18:0": ["oak_leaves", {"persistent": false}],
122 | "18:1": ["spruce_leaves", {"persistent": false}],
123 | "18:2": ["birch_leaves", {"persistent": false}],
124 | "18:3": ["jungle_leaves", {"persistent": false}],
125 | "18:4": ["oak_leaves", {"persistent": true}],
126 | "18:5": ["spruce_leaves", {"persistent": true}],
127 | "18:6": ["birch_leaves", {"persistent": true}],
128 | "18:7": ["jungle_leaves", {"persistent": true}],
129 | "18:8": ["oak_leaves", {"persistent": false}],
130 | "18:9": ["spruce_leaves", {"persistent": false}],
131 | "18:10": ["birch_leaves", {"persistent": false}],
132 | "18:11": ["jungle_leaves", {"persistent": false}],
133 | "18:12": ["oak_leaves", {"persistent": true}],
134 | "18:13": ["spruce_leaves", {"persistent": true}],
135 | "18:14": ["birch_leaves", {"persistent": true}],
136 | "18:15": ["jungle_leaves", {"persistent": true}],
137 |
138 | "19:0": ["sponge", null],
139 | "19:1": ["wet_sponge", null],
140 | "20:0": ["glass", null],
141 | "21:0": ["lapis_ore", null],
142 | "22:0": ["lapis_block", null],
143 |
144 | "23:0": ["dispenser", null],
145 | "23:0": ["dispenser", {"facing": "down", "triggered": false}],
146 | "23:1": ["dispenser", {"facing": "up", "triggered": false}],
147 | "23:2": ["dispenser", {"facing": "north", "triggered": false}],
148 | "23:3": ["dispenser", {"facing": "south", "triggered": false}],
149 | "23:4": ["dispenser", {"facing": "west", "triggered": false}],
150 | "23:5": ["dispenser", {"facing": "east", "triggered": false}],
151 | "23:8": ["dispenser", {"facing": "down", "triggered": true}],
152 | "23:9": ["dispenser", {"facing": "up", "triggered": true}],
153 | "23:10": ["dispenser", {"facing": "north", "triggered": true}],
154 | "23:11": ["dispenser", {"facing": "south", "triggered": true}],
155 | "23:12": ["dispenser", {"facing": "west", "triggered": true}],
156 | "23:13": ["dispenser", {"facing": "east", "triggered": true}],
157 |
158 | "24:0": ["sandstone", null],
159 | "24:1": ["chiseled_sandstone", null],
160 | "24:2": ["cut_sandstone", null],
161 | "25:0": ["note_block", null],
162 |
163 | "26:0": ["bed", {"facing": "south", "occupied": false, "part": "foot"}],
164 | "26:1": ["bed", {"facing": "west", "occupied": false, "part": "foot"}],
165 | "26:2": ["bed", {"facing": "north", "occupied": false, "part": "foot"}],
166 | "26:3": ["bed", {"facing": "east", "occupied": false, "part": "foot"}],
167 | "26:4": ["bed", {"facing": "south", "occupied": true, "part": "foot"}],
168 | "26:5": ["bed", {"facing": "west", "occupied": true, "part": "foot"}],
169 | "26:6": ["bed", {"facing": "north", "occupied": true, "part": "foot"}],
170 | "26:7": ["bed", {"facing": "east", "occupied": true, "part": "foot"}],
171 | "26:8": ["bed", {"facing": "south", "occupied": false, "part": "head"}],
172 | "26:9": ["bed", {"facing": "west", "occupied": false, "part": "head"}],
173 | "26:10": ["bed", {"facing": "north", "occupied": false, "part": "head"}],
174 | "26:11": ["bed", {"facing": "east", "occupied": false, "part": "head"}],
175 | "26:12": ["bed", {"facing": "south", "occupied": true, "part": "head"}],
176 | "26:13": ["bed", {"facing": "west", "occupied": true, "part": "head"}],
177 | "26:14": ["bed", {"facing": "north", "occupied": true, "part": "head"}],
178 | "26:15": ["bed", {"facing": "east", "occupied": true, "part": "head"}],
179 |
180 | "27:0": ["powered_rail", {"shape": "north_south", "powered": false}],
181 | "27:1": ["powered_rail", {"shape": "east_west", "powered": false}],
182 | "27:2": ["powered_rail", {"shape": "ascending_east", "powered": false}],
183 | "27:3": ["powered_rail", {"shape": "ascending_west", "powered": false}],
184 | "27:4": ["powered_rail", {"shape": "ascending_north", "powered": false}],
185 | "27:5": ["powered_rail", {"shape": "ascending_south", "powered": false}],
186 | "27:8": ["powered_rail", {"shape": "north_south", "powered": true}],
187 | "27:9": ["powered_rail", {"shape": "east_west", "powered": true}],
188 | "27:10": ["powered_rail", {"shape": "ascending_east", "powered": true}],
189 | "27:11": ["powered_rail", {"shape": "ascending_west", "powered": true}],
190 | "27:12": ["powered_rail", {"shape": "ascending_north", "powered": true}],
191 | "27:13": ["powered_rail", {"shape": "ascending_south", "powered": true}],
192 |
193 | "28:0": ["detector_rail", {"shape": "north_south", "powered": false}],
194 | "28:1": ["detector_rail", {"shape": "east_west", "powered": false}],
195 | "28:2": ["detector_rail", {"shape": "ascending_east", "powered": false}],
196 | "28:3": ["detector_rail", {"shape": "ascending_west", "powered": false}],
197 | "28:4": ["detector_rail", {"shape": "ascending_north", "powered": false}],
198 | "28:5": ["detector_rail", {"shape": "ascending_south", "powered": false}],
199 | "28:8": ["detector_rail", {"shape": "north_south", "powered": true}],
200 | "28:9": ["detector_rail", {"shape": "east_west", "powered": true}],
201 | "28:10": ["detector_rail", {"shape": "ascending_east", "powered": true}],
202 | "28:11": ["detector_rail", {"shape": "ascending_west", "powered": true}],
203 | "28:12": ["detector_rail", {"shape": "ascending_north", "powered": true}],
204 | "28:13": ["detector_rail", {"shape": "ascending_south", "powered": true}],
205 |
206 | "29:0": ["sticky_piston", {"facing": "down", "extended": false}],
207 | "29:1": ["sticky_piston", {"facing": "up", "extended": false}],
208 | "29:2": ["sticky_piston", {"facing": "north", "extended": false}],
209 | "29:3": ["sticky_piston", {"facing": "south", "extended": false}],
210 | "29:4": ["sticky_piston", {"facing": "west", "extended": false}],
211 | "29:5": ["sticky_piston", {"facing": "east", "extended": false}],
212 | "29:8": ["sticky_piston", {"facing": "down", "extended": true}],
213 | "29:9": ["sticky_piston", {"facing": "up", "extended": true}],
214 | "29:10": ["sticky_piston", {"facing": "north", "extended": true}],
215 | "29:11": ["sticky_piston", {"facing": "south", "extended": true}],
216 | "29:12": ["sticky_piston", {"facing": "west", "extended": true}],
217 | "29:13": ["sticky_piston", {"facing": "east", "extended": true}],
218 |
219 | "30:0": ["cobweb", null],
220 | "31:0": ["dead_shrub", null],
221 | "31:1": ["grass", null],
222 | "31:2": ["fern", null],
223 | "32:0": ["dead_bush", null],
224 |
225 | "33:0": ["piston", {"facing": "down", "extended": false}],
226 | "33:1": ["piston", {"facing": "up", "extended": false}],
227 | "33:2": ["piston", {"facing": "north", "extended": false}],
228 | "33:3": ["piston", {"facing": "south", "extended": false}],
229 | "33:4": ["piston", {"facing": "west", "extended": false}],
230 | "33:5": ["piston", {"facing": "east", "extended": false}],
231 | "33:8": ["piston", {"facing": "down", "extended": true}],
232 | "33:9": ["piston", {"facing": "up", "extended": true}],
233 | "33:10": ["piston", {"facing": "north", "extended": true}],
234 | "33:11": ["piston", {"facing": "south", "extended": true}],
235 | "33:12": ["piston", {"facing": "west", "extended": true}],
236 | "33:13": ["piston", {"facing": "east", "extended": true}],
237 |
238 | "34:0": ["piston_head", {"facing": "down", "type": "normal"}],
239 | "34:1": ["piston_head", {"facing": "up", "type": "normal"}],
240 | "34:2": ["piston_head", {"facing": "north", "type": "normal"}],
241 | "34:3": ["piston_head", {"facing": "south", "type": "normal"}],
242 | "34:4": ["piston_head", {"facing": "west", "type": "normal"}],
243 | "34:5": ["piston_head", {"facing": "east", "type": "normal"}],
244 | "34:8": ["piston_head", {"facing": "down", "type": "sticky"}],
245 | "34:9": ["piston_head", {"facing": "up", "type": "sticky"}],
246 | "34:10": ["piston_head", {"facing": "north", "type": "sticky"}],
247 | "34:11": ["piston_head", {"facing": "south", "type": "sticky"}],
248 | "34:12": ["piston_head", {"facing": "west", "type": "sticky"}],
249 | "34:13": ["piston_head", {"facing": "east", "type": "sticky"}],
250 |
251 | "35:0": ["white_wool", null],
252 | "35:1": ["orange_wool", null],
253 | "35:2": ["magenta_wool", null],
254 | "35:3": ["light_blue_wool", null],
255 | "35:4": ["yellow_wool", null],
256 | "35:5": ["lime_wool", null],
257 | "35:6": ["pink_wool", null],
258 | "35:7": ["gray_wool", null],
259 | "35:8": ["light_gray_wool", null],
260 | "35:9": ["cyan_wool", null],
261 | "35:10": ["purple_wool", null],
262 | "35:11": ["blue_wool", null],
263 | "35:12": ["brown_wool", null],
264 | "35:13": ["green_wool", null],
265 | "35:14": ["red_wool", null],
266 | "35:15": ["black_wool", null],
267 | "37:0": ["dandelion", null],
268 | "38:0": ["poppy", null],
269 | "38:1": ["blue_orchid", null],
270 | "38:2": ["allium", null],
271 | "38:3": ["azure_bluet", null],
272 | "38:4": ["red_tulip", null],
273 | "38:5": ["orange_tulip", null],
274 | "38:6": ["white_tulip", null],
275 | "38:7": ["pink_tulip", null],
276 | "38:8": ["oxeye_daisy", null],
277 | "39:0": ["brown_mushroom", null],
278 | "40:0": ["red_mushroom", null],
279 | "41:0": ["gold_block", null],
280 | "42:0": ["iron_block", null],
281 |
282 | "43:0": ["smooth_stone_slab", {"type": "double"}],
283 | "43:1": ["sandstone_slab", {"type": "double"}],
284 | "43:2": ["petrified_oak_slab", {"type": "double"}],
285 | "43:3": ["cobblestone_slab", {"type": "double"}],
286 | "43:4": ["brick_slab", {"type": "double"}],
287 | "43:5": ["stone_brick_slab", {"type": "double"}],
288 | "43:6": ["nether_brick_slab", {"type": "double"}],
289 | "43:7": ["quartz_slab", {"type": "double"}],
290 | "43:8": ["smooth_stone", null],
291 | "43:9": ["smooth_sandstone", null],
292 | "43:10": ["petrified_oak_slab", {"type": "double"}],
293 | "43:11": ["cobblestone_slab", {"type": "double"}],
294 | "43:12": ["brick_slab", {"type": "double"}],
295 | "43:13": ["stone_brick_slab", {"type": "double"}],
296 | "43:14": ["nether_brick_slab", {"type": "double"}],
297 | "43:15": ["smooth_quartz", null],
298 |
299 | "44:0": ["smooth_stone_slab", {"type": "bottom"}],
300 | "44:1": ["sandstone_slab", {"type": "bottom"}],
301 | "44:2": ["wooden_slab", {"type": "bottom"}],
302 | "44:3": ["cobblestone_slab", {"type": "bottom"}],
303 | "44:4": ["brick_slab", {"type": "bottom"}],
304 | "44:5": ["stone_brick_slab", {"type": "bottom"}],
305 | "44:6": ["nether_brick_slab", {"type": "bottom"}],
306 | "44:7": ["quartz_slab", {"type": "bottom"}],
307 | "44:8": ["smooth_stone_slab", {"type": "top"}],
308 | "44:9": ["sandstone_slab", {"type": "top"}],
309 | "44:10": ["wooden_slab", {"type": "top"}],
310 | "44:11": ["cobblestone_slab", {"type": "top"}],
311 | "44:12": ["brick_slab", {"type": "top"}],
312 | "44:13": ["stone_brick_slab", {"type": "top"}],
313 | "44:14": ["nether_brick_slab", {"type": "top"}],
314 | "44:15": ["quartz_slab", {"type": "top"}],
315 |
316 | "45:0": ["bricks", null],
317 | "46:0": ["tnt", null],
318 | "47:0": ["bookshelf", null],
319 | "48:0": ["mossy_cobblestone", null],
320 | "49:0": ["obsidian", null],
321 |
322 | "50:0": ["torch", null],
323 | "50:1": ["wall_torch", {"facing": "east"}],
324 | "50:2": ["wall_torch", {"facing": "west"}],
325 | "50:3": ["wall_torch", {"facing": "south"}],
326 | "50:4": ["wall_torch", {"facing": "north"}],
327 | "50:5": ["torch", null],
328 |
329 | "51:0": ["fire", null],
330 | "51:1": ["fire", null],
331 | "51:2": ["fire", null],
332 | "51:3": ["fire", null],
333 | "51:4": ["fire", null],
334 | "51:5": ["fire", null],
335 | "51:6": ["fire", null],
336 | "51:7": ["fire", null],
337 | "51:8": ["fire", null],
338 | "51:9": ["fire", null],
339 | "51:10": ["fire", null],
340 | "51:11": ["fire", null],
341 | "51:12": ["fire", null],
342 | "51:13": ["fire", null],
343 | "51:14": ["fire", null],
344 | "51:15": ["fire", null],
345 |
346 | "52:0": ["spawner", null],
347 |
348 | "53:0": ["oak_stairs", {"facing": "east", "half": "bottom"}],
349 | "53:1": ["oak_stairs", {"facing": "west", "half": "bottom"}],
350 | "53:2": ["oak_stairs", {"facing": "south", "half": "bottom"}],
351 | "53:3": ["oak_stairs", {"facing": "north", "half": "bottom"}],
352 | "53:4": ["oak_stairs", {"facing": "east", "half": "top"}],
353 | "53:5": ["oak_stairs", {"facing": "west", "half": "top"}],
354 | "53:6": ["oak_stairs", {"facing": "south", "half": "top"}],
355 | "53:7": ["oak_stairs", {"facing": "north", "half": "top"}],
356 |
357 | "54:0": ["chest", {"facing": "north"}],
358 | "54:1": ["chest", {"facing": "north"}],
359 | "54:2": ["chest", {"facing": "north"}],
360 | "54:3": ["chest", {"facing": "south"}],
361 | "54:4": ["chest", {"facing": "west"}],
362 | "54:5": ["chest", {"facing": "east"}],
363 |
364 |
365 | "55:0": ["redstone_wire", {"power": 0}],
366 | "55:1": ["redstone_wire", {"power": 1}],
367 | "55:2": ["redstone_wire", {"power": 2}],
368 | "55:3": ["redstone_wire", {"power": 3}],
369 | "55:4": ["redstone_wire", {"power": 4}],
370 | "55:5": ["redstone_wire", {"power": 5}],
371 | "55:6": ["redstone_wire", {"power": 6}],
372 | "55:7": ["redstone_wire", {"power": 7}],
373 | "55:8": ["redstone_wire", {"power": 8}],
374 | "55:9": ["redstone_wire", {"power": 9}],
375 | "55:10": ["redstone_wire", {"power": 10}],
376 | "55:11": ["redstone_wire", {"power": 11}],
377 | "55:12": ["redstone_wire", {"power": 12}],
378 | "55:13": ["redstone_wire", {"power": 13}],
379 | "55:14": ["redstone_wire", {"power": 14}],
380 | "55:15": ["redstone_wire", {"power": 15}],
381 |
382 |
383 | "56:0": ["diamond_ore", null],
384 | "57:0": ["diamond_block", null],
385 | "58:0": ["crafting_table", null],
386 |
387 | "59:0": ["wheat", {"age": 0}],
388 | "59:1": ["wheat", {"age": 1}],
389 | "59:2": ["wheat", {"age": 2}],
390 | "59:3": ["wheat", {"age": 3}],
391 | "59:4": ["wheat", {"age": 4}],
392 | "59:5": ["wheat", {"age": 5}],
393 | "59:6": ["wheat", {"age": 6}],
394 | "59:7": ["wheat", {"age": 7}],
395 |
396 | "60:0": ["farmland", {"moisture": 0}],
397 | "60:1": ["farmland", {"moisture": 1}],
398 | "60:2": ["farmland", {"moisture": 2}],
399 | "60:3": ["farmland", {"moisture": 3}],
400 | "60:4": ["farmland", {"moisture": 4}],
401 | "60:5": ["farmland", {"moisture": 5}],
402 | "60:6": ["farmland", {"moisture": 6}],
403 | "60:7": ["farmland", {"moisture": 7}],
404 |
405 | "61:0": ["furnace", {"lit": false, "facing": "north"}],
406 | "61:1": ["furnace", {"lit": false, "facing": "north"}],
407 | "61:2": ["furnace", {"lit": false, "facing": "north"}],
408 | "61:3": ["furnace", {"lit": false, "facing": "south"}],
409 | "61:4": ["furnace", {"lit": false, "facing": "west"}],
410 | "61:5": ["furnace", {"lit": false, "facing": "east"}],
411 |
412 | "62:0": ["furnace", {"lit": true, "facing": "north"}],
413 | "61:1": ["furnace", {"lit": false, "facing": "north"}],
414 | "62:2": ["furnace", {"lit": true, "facing": "north"}],
415 | "62:3": ["furnace", {"lit": true, "facing": "south"}],
416 | "62:4": ["furnace", {"lit": true, "facing": "west"}],
417 | "62:5": ["furnace", {"lit": true, "facing": "east"}],
418 |
419 | "63:0": ["oak_sign", {"rotation": 0}],
420 | "63:1": ["oak_sign", {"rotation": 1}],
421 | "63:2": ["oak_sign", {"rotation": 2}],
422 | "63:3": ["oak_sign", {"rotation": 3}],
423 | "63:4": ["oak_sign", {"rotation": 4}],
424 | "63:5": ["oak_sign", {"rotation": 5}],
425 | "63:6": ["oak_sign", {"rotation": 6}],
426 | "63:7": ["oak_sign", {"rotation": 7}],
427 | "63:8": ["oak_sign", {"rotation": 8}],
428 | "63:9": ["oak_sign", {"rotation": 9}],
429 | "63:10": ["oak_sign", {"rotation": 10}],
430 | "63:11": ["oak_sign", {"rotation": 11}],
431 | "63:12": ["oak_sign", {"rotation": 12}],
432 | "63:13": ["oak_sign", {"rotation": 13}],
433 | "63:14": ["oak_sign", {"rotation": 14}],
434 | "63:15": ["oak_sign", {"rotation": 15}],
435 |
436 |
437 | "64:0": ["oak_door", {"half": "lower", "facing": "east", "open": false}],
438 | "64:1": ["oak_door", {"half": "lower", "facing": "south", "open": false}],
439 | "64:2": ["oak_door", {"half": "lower", "facing": "west", "open": false}],
440 | "64:3": ["oak_door", {"half": "lower", "facing": "north", "open": false}],
441 | "64:4": ["oak_door", {"half": "lower", "facing": "east", "open": true}],
442 | "64:5": ["oak_door", {"half": "lower", "facing": "south", "open": true}],
443 | "64:6": ["oak_door", {"half": "lower", "facing": "west", "open": true}],
444 | "64:7": ["oak_door", {"half": "lower", "facing": "north", "open": true}],
445 |
446 | "64:8": ["oak_door", {"half": "upper", "hinge": "left", "powered": false}],
447 | "64:9": ["oak_door", {"half": "upper", "hinge": "right", "powered": false}],
448 | "64:10": ["oak_door", {"half": "upper", "hinge": "left", "powered": true}],
449 | "64:11": ["oak_door", {"half": "upper", "hinge": "right", "powered": true}],
450 |
451 | "65:0": ["ladder", {"facing": "north"}],
452 | "65:1": ["ladder", {"facing": "north"}],
453 | "65:2": ["ladder", {"facing": "north"}],
454 | "65:3": ["ladder", {"facing": "south"}],
455 | "65:4": ["ladder", {"facing": "west"}],
456 | "65:5": ["ladder", {"facing": "east"}],
457 |
458 | "66:0": ["rail", {"shape": "north_south"}],
459 | "66:1": ["rail", {"shape": "east_west"}],
460 | "66:2": ["rail", {"shape": "ascending_east"}],
461 | "66:3": ["rail", {"shape": "ascending_west"}],
462 | "66:4": ["rail", {"shape": "ascending_north"}],
463 | "66:5": ["rail", {"shape": "ascending_south"}],
464 | "66:6": ["rail", {"shape": "south_east"}],
465 | "66:7": ["rail", {"shape": "south_west"}],
466 | "66:8": ["rail", {"shape": "north_west"}],
467 | "66:9": ["rail", {"shape": "north_east"}],
468 |
469 | "67:0": ["cobblestone_stairs", {"facing": "east", "half": "bottom"}],
470 | "67:1": ["cobblestone_stairs", {"facing": "west", "half": "bottom"}],
471 | "67:2": ["cobblestone_stairs", {"facing": "south", "half": "bottom"}],
472 | "67:3": ["cobblestone_stairs", {"facing": "north", "half": "bottom"}],
473 | "67:4": ["cobblestone_stairs", {"facing": "east", "half": "top"}],
474 | "67:5": ["cobblestone_stairs", {"facing": "west", "half": "top"}],
475 | "67:6": ["cobblestone_stairs", {"facing": "south", "half": "top"}],
476 | "67:7": ["cobblestone_stairs", {"facing": "north", "half": "top"}],
477 |
478 | "68:0": ["oak_wall_sign", {"facing": "north"}],
479 | "68:1": ["oak_wall_sign", {"facing": "north"}],
480 | "68:2": ["oak_wall_sign", {"facing": "north"}],
481 | "68:3": ["oak_wall_sign", {"facing": "south"}],
482 | "68:4": ["oak_wall_sign", {"facing": "west"}],
483 | "68:5": ["oak_wall_sign", {"facing": "east"}],
484 |
485 | "69:0": ["lever", {"face": "ceiling", "facing": "west", "powered": false}],
486 |
487 | "69:1": ["lever", {"face": "wall", "facing": "east", "powered": false}],
488 | "69:2": ["lever", {"face": "wall", "facing": "west", "powered": false}],
489 | "69:3": ["lever", {"face": "wall", "facing": "south", "powered": false}],
490 | "69:4": ["lever", {"face": "wall", "facing": "north", "powered": false}],
491 |
492 | "69:5": ["lever", {"face": "floor", "facing": "north", "powered": false}],
493 | "69:6": ["lever", {"face": "floor", "facing": "west", "powered": false}],
494 | "69:7": ["lever", {"face": "ceiling", "facing": "north", "powered": false}],
495 | "69:8": ["lever", {"face": "ceiling", "facing": "west", "powered": true}],
496 |
497 | "69:9": ["lever", {"face": "wall", "facing": "east", "powered": true}],
498 | "69:10": ["lever", {"face": "wall", "facing": "west", "powered": true}],
499 | "69:11": ["lever", {"face": "wall", "facing": "south", "powered": true}],
500 | "69:12": ["lever", {"face": "wall", "facing": "north", "powered": true}],
501 |
502 | "69:13": ["lever", {"face": "floor", "facing": "north", "powered": true}],
503 | "69:14": ["lever", {"face": "floor", "facing": "west", "powered": true}],
504 | "69:15": ["lever", {"face": "ceiling", "facing": "north", "powered": true}],
505 |
506 | "70:0": ["stone_pressure_plate", {"powered": false}],
507 | "70:1": ["stone_pressure_plate", {"powered": true}],
508 |
509 | "71:0": ["iron_door", {"half": "lower", "facing": "east", "open": false}],
510 | "71:1": ["iron_door", {"half": "lower", "facing": "south", "open": false}],
511 | "71:2": ["iron_door", {"half": "lower", "facing": "west", "open": false}],
512 | "71:3": ["iron_door", {"half": "lower", "facing": "north", "open": false}],
513 | "71:4": ["iron_door", {"half": "lower", "facing": "east", "open": true}],
514 | "71:5": ["iron_door", {"half": "lower", "facing": "south", "open": true}],
515 | "71:6": ["iron_door", {"half": "lower", "facing": "west", "open": true}],
516 | "71:7": ["iron_door", {"half": "lower", "facing": "north", "open": true}],
517 |
518 | "71:8": ["iron_door", {"half": "upper", "hinge": "left", "powered": false}],
519 | "71:9": ["iron_door", {"half": "upper", "hinge": "right", "powered": false}],
520 | "71:10": ["iron_door", {"half": "upper", "hinge": "left", "powered": true}],
521 | "71:11": ["iron_door", {"half": "upper", "hinge": "right", "powered": true}],
522 |
523 | "72:0": ["oak_pressure_plate", {"powered": false}],
524 | "72:1": ["oak_pressure_plate", {"powered": true}],
525 |
526 | "73:0": ["redstone_ore", {"lit": false}],
527 | "74:0": ["redstone_ore", {"lit": true}],
528 |
529 | "75:0": ["redstone_torch", {"lit": false}],
530 | "75:1": ["redstone_wall_torch", {"facing": "east", "lit": false}],
531 | "75:2": ["redstone_wall_torch", {"facing": "west", "lit": false}],
532 | "75:3": ["redstone_wall_torch", {"facing": "south", "lit": false}],
533 | "75:4": ["redstone_wall_torch", {"facing": "north", "lit": false}],
534 | "75:5": ["redstone_torch", {"lit": false}],
535 |
536 | "76:0": ["redstone_torch", {"lit": true}],
537 | "76:1": ["redstone_wall_torch", {"facing": "east", "lit": true}],
538 | "76:2": ["redstone_wall_torch", {"facing": "west", "lit": true}],
539 | "76:3": ["redstone_wall_torch", {"facing": "south", "lit": true}],
540 | "76:4": ["redstone_wall_torch", {"facing": "north", "lit": true}],
541 | "76:5": ["redstone_torch", {"lit": true}],
542 |
543 | "77:0": ["stone_button", {"face": "ceiling", "powered": false}],
544 | "77:1": ["stone_button", {"face": "wall", "facing": "east", "powered": false}],
545 | "77:2": ["stone_button", {"face": "wall", "facing": "west", "powered": false}],
546 | "77:3": ["stone_button", {"face": "wall", "facing": "south", "powered": false}],
547 | "77:4": ["stone_button", {"face": "wall", "facing": "north", "powered": false}],
548 | "77:5": ["stone_button", {"face": "floor", "powered": false}],
549 | "77:8": ["stone_button", {"face": "ceiling", "powered": true}],
550 | "77:9": ["stone_button", {"face": "wall", "facing": "east", "powered": true}],
551 | "77:10": ["stone_button", {"face": "wall", "facing": "west", "powered": true}],
552 | "77:11": ["stone_button", {"face": "wall", "facing": "south", "powered": true}],
553 | "77:12": ["stone_button", {"face": "wall", "facing": "north", "powered": true}],
554 | "77:13": ["stone_button", {"face": "floor", "powered": true}],
555 |
556 | "78:0": ["snow", {"layers": 1}],
557 | "78:1": ["snow", {"layers": 2}],
558 | "78:2": ["snow", {"layers": 3}],
559 | "78:3": ["snow", {"layers": 4}],
560 | "78:4": ["snow", {"layers": 5}],
561 | "78:5": ["snow", {"layers": 6}],
562 | "78:6": ["snow", {"layers": 7}],
563 | "78:7": ["snow", {"layers": 8}],
564 |
565 | "79:0": ["ice", null],
566 | "80:0": ["snow_block", null],
567 |
568 | "81:0": ["cactus", {"age": 0}],
569 | "81:1": ["cactus", {"age": 1}],
570 | "81:2": ["cactus", {"age": 2}],
571 | "81:3": ["cactus", {"age": 3}],
572 | "81:4": ["cactus", {"age": 4}],
573 | "81:5": ["cactus", {"age": 5}],
574 | "81:6": ["cactus", {"age": 6}],
575 | "81:7": ["cactus", {"age": 7}],
576 | "81:8": ["cactus", {"age": 8}],
577 | "81:9": ["cactus", {"age": 9}],
578 | "81:10": ["cactus", {"age": 10}],
579 | "81:11": ["cactus", {"age": 11}],
580 | "81:12": ["cactus", {"age": 12}],
581 | "81:13": ["cactus", {"age": 13}],
582 | "81:14": ["cactus", {"age": 14}],
583 | "81:15": ["cactus", {"age": 15}],
584 |
585 | "82:0": ["clay", null],
586 |
587 | "83:0": ["sugar_cane", {"age": 0}],
588 | "83:1": ["sugar_cane", {"age": 1}],
589 | "83:2": ["sugar_cane", {"age": 2}],
590 | "83:3": ["sugar_cane", {"age": 3}],
591 | "83:4": ["sugar_cane", {"age": 4}],
592 | "83:5": ["sugar_cane", {"age": 5}],
593 | "83:6": ["sugar_cane", {"age": 6}],
594 | "83:7": ["sugar_cane", {"age": 7}],
595 | "83:8": ["sugar_cane", {"age": 8}],
596 | "83:9": ["sugar_cane", {"age": 9}],
597 | "83:10": ["sugar_cane", {"age": 10}],
598 | "83:11": ["sugar_cane", {"age": 11}],
599 | "83:12": ["sugar_cane", {"age": 12}],
600 | "83:13": ["sugar_cane", {"age": 13}],
601 | "83:14": ["sugar_cane", {"age": 14}],
602 | "83:15": ["sugar_cane", {"age": 15}],
603 |
604 | "84:0": ["jukebox", {"has_record": false}],
605 | "84:1": ["jukebox", {"has_record": true}],
606 |
607 | "85:0": ["oak_fence", null],
608 |
609 | "86:0": ["carved_pumpkin", {"facing": "south"}],
610 | "86:1": ["carved_pumpkin", {"facing": "west"}],
611 | "86:2": ["carved_pumpkin", {"facing": "north"}],
612 | "86:3": ["carved_pumpkin", {"facing": "east"}],
613 |
614 | "87:0": ["netherrack", null],
615 | "88:0": ["soul_sand", null],
616 | "89:0": ["glowstone", null],
617 |
618 | "90:0": ["nether_portal", null],
619 | "90:1": ["nether_portal", {"axis": "z"}],
620 | "90:2": ["nether_portal", {"axis": "x"}],
621 |
622 | "91:0": ["jack_o_lantern", {"facing": "south"}],
623 | "91:1": ["jack_o_lantern", {"facing": "west"}],
624 | "91:2": ["jack_o_lantern", {"facing": "north"}],
625 | "91:3": ["jack_o_lantern", {"facing": "east"}],
626 |
627 | "92:0": ["cake", {"bites": 0}],
628 | "92:1": ["cake", {"bites": 1}],
629 | "92:2": ["cake", {"bites": 2}],
630 | "92:3": ["cake", {"bites": 3}],
631 | "92:4": ["cake", {"bites": 4}],
632 | "92:5": ["cake", {"bites": 5}],
633 | "92:6": ["cake", {"bites": 6}],
634 |
635 | "93:0": ["repeater", {"facing": "south", "delay": 1, "powered": false}],
636 | "93:1": ["repeater", {"facing": "west", "delay": 1, "powered": false}],
637 | "93:2": ["repeater", {"facing": "north", "delay": 1, "powered": false}],
638 | "93:3": ["repeater", {"facing": "east", "delay": 1, "powered": false}],
639 | "93:4": ["repeater", {"facing": "south", "delay": 2, "powered": false}],
640 | "93:5": ["repeater", {"facing": "west", "delay": 2, "powered": false}],
641 | "93:6": ["repeater", {"facing": "north", "delay": 2, "powered": false}],
642 | "93:7": ["repeater", {"facing": "east", "delay": 2, "powered": false}],
643 | "93:8": ["repeater", {"facing": "south", "delay": 3, "powered": false}],
644 | "93:9": ["repeater", {"facing": "west", "delay": 3, "powered": false}],
645 | "93:10": ["repeater", {"facing": "north", "delay": 3, "powered": false}],
646 | "93:11": ["repeater", {"facing": "east", "delay": 3, "powered": false}],
647 | "93:12": ["repeater", {"facing": "south", "delay": 4, "powered": false}],
648 | "93:13": ["repeater", {"facing": "west", "delay": 4, "powered": false}],
649 | "93:14": ["repeater", {"facing": "north", "delay": 4, "powered": false}],
650 | "93:15": ["repeater", {"facing": "east", "delay": 4, "powered": false}],
651 |
652 | "94:0": ["repeater", {"facing": "south", "delay": 1, "powered": true}],
653 | "94:1": ["repeater", {"facing": "west", "delay": 1, "powered": true}],
654 | "94:2": ["repeater", {"facing": "north", "delay": 1, "powered": true}],
655 | "94:3": ["repeater", {"facing": "east", "delay": 1, "powered": true}],
656 | "94:4": ["repeater", {"facing": "south", "delay": 2, "powered": true}],
657 | "94:5": ["repeater", {"facing": "west", "delay": 2, "powered": true}],
658 | "94:6": ["repeater", {"facing": "north", "delay": 2, "powered": true}],
659 | "94:7": ["repeater", {"facing": "east", "delay": 2, "powered": true}],
660 | "94:8": ["repeater", {"facing": "south", "delay": 3, "powered": true}],
661 | "94:9": ["repeater", {"facing": "west", "delay": 3, "powered": true}],
662 | "94:10": ["repeater", {"facing": "north", "delay": 3, "powered": true}],
663 | "94:11": ["repeater", {"facing": "east", "delay": 3, "powered": true}],
664 | "94:12": ["repeater", {"facing": "south", "delay": 4, "powered": true}],
665 | "94:13": ["repeater", {"facing": "west", "delay": 4, "powered": true}],
666 | "94:14": ["repeater", {"facing": "north", "delay": 4, "powered": true}],
667 | "94:15": ["repeater", {"facing": "east", "delay": 4, "powered": true}],
668 |
669 | "95:0": ["white_stained_glass", null],
670 | "95:1": ["orange_stained_glass", null],
671 | "95:2": ["magenta_stained_glass", null],
672 | "95:3": ["light_blue_stained_glass", null],
673 | "95:4": ["yellow_stained_glass", null],
674 | "95:5": ["lime_stained_glass", null],
675 | "95:6": ["pink_stained_glass", null],
676 | "95:7": ["gray_stained_glass", null],
677 | "95:8": ["light_gray_stained_glass", null],
678 | "95:9": ["cyan_stained_glass", null],
679 | "95:10": ["purple_stained_glass", null],
680 | "95:11": ["blue_stained_glass", null],
681 | "95:12": ["brown_stained_glass", null],
682 | "95:13": ["green_stained_glass", null],
683 | "95:14": ["red_stained_glass", null],
684 | "95:15": ["black_stained_glass", null],
685 |
686 | "96:0": ["oak_trapdoor", {"facing": "north", "open": false, "half": "bottom"}],
687 | "96:1": ["oak_trapdoor", {"facing": "south", "open": false, "half": "bottom"}],
688 | "96:2": ["oak_trapdoor", {"facing": "west", "open": false, "half": "bottom"}],
689 | "96:3": ["oak_trapdoor", {"facing": "east", "open": false, "half": "bottom"}],
690 | "96:4": ["oak_trapdoor", {"facing": "north", "open": true, "half": "bottom"}],
691 | "96:5": ["oak_trapdoor", {"facing": "south", "open": true, "half": "bottom"}],
692 | "96:6": ["oak_trapdoor", {"facing": "west", "open": true, "half": "bottom"}],
693 | "96:7": ["oak_trapdoor", {"facing": "east", "open": true, "half": "bottom"}],
694 | "96:8": ["oak_trapdoor", {"facing": "north", "open": false, "half": "top"}],
695 | "96:9": ["oak_trapdoor", {"facing": "south", "open": false, "half": "top"}],
696 | "96:10": ["oak_trapdoor", {"facing": "west", "open": false, "half": "top"}],
697 | "96:11": ["oak_trapdoor", {"facing": "east", "open": false, "half": "top"}],
698 | "96:12": ["oak_trapdoor", {"facing": "north", "open": true, "half": "top"}],
699 | "96:13": ["oak_trapdoor", {"facing": "south", "open": true, "half": "top"}],
700 | "96:14": ["oak_trapdoor", {"facing": "west", "open": true, "half": "top"}],
701 | "96:15": ["oak_trapdoor", {"facing": "east", "open": true, "half": "top"}],
702 |
703 |
704 | "97:0": ["infested_stone", null],
705 | "97:1": ["infested_cobblestone", null],
706 | "97:2": ["infested_stone_bricks", null],
707 | "97:3": ["infested_mossy_stone_bricks", null],
708 | "97:4": ["infested_cracked_stone_bricks", null],
709 | "97:5": ["infested_chiseled_stone_bricks", null],
710 | "98:0": ["stone_bricks", null],
711 | "98:1": ["mossy_stone_bricks", null],
712 | "98:2": ["cracked_stone_bricks", null],
713 | "98:3": ["chiseled_stone_bricks", null],
714 |
715 | "99:0": ["brown_mushroom_block", null],
716 | "99:1": ["brown_mushroom_block", null],
717 | "99:2": ["brown_mushroom_block", null],
718 | "99:3": ["brown_mushroom_block", null],
719 | "99:4": ["brown_mushroom_block", null],
720 | "99:5": ["brown_mushroom_block", null],
721 | "99:6": ["brown_mushroom_block", null],
722 | "99:7": ["brown_mushroom_block", null],
723 | "99:8": ["brown_mushroom_block", null],
724 | "99:9": ["brown_mushroom_block", null],
725 | "99:10": ["brown_mushroom_block", null],
726 | "99:11": ["brown_mushroom_block", null],
727 | "99:12": ["brown_mushroom_block", null],
728 | "99:13": ["brown_mushroom_block", null],
729 | "99:14": ["brown_mushroom_block", null],
730 | "99:15": ["brown_mushroom_block", null],
731 |
732 | "100:0": ["red_mushroom_block", null],
733 | "100:1": ["red_mushroom_block", null],
734 | "100:2": ["red_mushroom_block", null],
735 | "100:3": ["red_mushroom_block", null],
736 | "100:4": ["red_mushroom_block", null],
737 | "100:5": ["red_mushroom_block", null],
738 | "100:6": ["red_mushroom_block", null],
739 | "100:7": ["red_mushroom_block", null],
740 | "100:8": ["red_mushroom_block", null],
741 | "100:9": ["red_mushroom_block", null],
742 | "100:10": ["red_mushroom_block", null],
743 | "100:11": ["red_mushroom_block", null],
744 | "100:12": ["red_mushroom_block", null],
745 | "100:13": ["red_mushroom_block", null],
746 | "100:14": ["red_mushroom_block", null],
747 | "100:15": ["red_mushroom_block", null],
748 |
749 |
750 | "101:0": ["iron_bars", null],
751 | "102:0": ["glass_pane", null],
752 | "103:0": ["melon", null],
753 |
754 | "104:0": ["pumpkin_stem", {"age": 0}],
755 | "104:1": ["pumpkin_stem", {"age": 1}],
756 | "104:2": ["pumpkin_stem", {"age": 2}],
757 | "104:3": ["pumpkin_stem", {"age": 3}],
758 | "104:4": ["pumpkin_stem", {"age": 4}],
759 | "104:5": ["pumpkin_stem", {"age": 5}],
760 | "104:6": ["pumpkin_stem", {"age": 6}],
761 | "104:7": ["pumpkin_stem", {"age": 7}],
762 |
763 | "105:0": ["melon_stem", {"age": 0}],
764 | "105:1": ["melon_stem", {"age": 1}],
765 | "105:2": ["melon_stem", {"age": 2}],
766 | "105:3": ["melon_stem", {"age": 3}],
767 | "105:4": ["melon_stem", {"age": 4}],
768 | "105:5": ["melon_stem", {"age": 5}],
769 | "105:6": ["melon_stem", {"age": 6}],
770 | "105:7": ["melon_stem", {"age": 7}],
771 |
772 | "106:0": ["vine", {"south": false, "west": false, "north": false, "east": false}],
773 | "106:1": ["vine", {"south": true, "west": false, "north": false, "east": false}],
774 | "106:2": ["vine", {"south": false, "west": true, "north": false, "east": false}],
775 | "106:3": ["vine", {"south": true, "west": true, "north": false, "east": false}],
776 | "106:4": ["vine", {"south": false, "west": false, "north": true, "east": false}],
777 | "106:5": ["vine", {"south": true, "west": false, "north": true, "east": false}],
778 | "106:6": ["vine", {"south": false, "west": true, "north": true, "east": false}],
779 | "106:7": ["vine", {"south": true, "west": true, "north": true, "east": false}],
780 | "106:8": ["vine", {"south": false, "west": false, "north": false, "east": true}],
781 | "106:9": ["vine", {"south": true, "west": false, "north": false, "east": true}],
782 | "106:10": ["vine", {"south": false, "west": true, "north": false, "east": true}],
783 | "106:11": ["vine", {"south": true, "west": true, "north": false, "east": true}],
784 | "106:12": ["vine", {"south": false, "west": false, "north": true, "east": true}],
785 | "106:13": ["vine", {"south": true, "west": false, "north": true, "east": true}],
786 | "106:14": ["vine", {"south": false, "west": true, "north": true, "east": true}],
787 | "106:15": ["vine", {"south": true, "west": true, "north": true, "east": true}],
788 |
789 | "107:0": ["oak_fence_gate", {"facing": "south", "open": false}],
790 | "107:1": ["oak_fence_gate", {"facing": "west", "open": false}],
791 | "107:2": ["oak_fence_gate", {"facing": "north", "open": false}],
792 | "107:3": ["oak_fence_gate", {"facing": "east", "open": false}],
793 | "107:4": ["oak_fence_gate", {"facing": "south", "open": true}],
794 | "107:5": ["oak_fence_gate", {"facing": "west", "open": true}],
795 | "107:6": ["oak_fence_gate", {"facing": "north", "open": true}],
796 | "107:7": ["oak_fence_gate", {"facing": "east", "open": true}],
797 |
798 | "108:0": ["brick_stairs", {"facing": "east", "half": "bottom"}],
799 | "108:1": ["brick_stairs", {"facing": "west", "half": "bottom"}],
800 | "108:2": ["brick_stairs", {"facing": "south", "half": "bottom"}],
801 | "108:3": ["brick_stairs", {"facing": "north", "half": "bottom"}],
802 | "108:4": ["brick_stairs", {"facing": "east", "half": "top"}],
803 | "108:5": ["brick_stairs", {"facing": "west", "half": "top"}],
804 | "108:6": ["brick_stairs", {"facing": "south", "half": "top"}],
805 | "108:7": ["brick_stairs", {"facing": "north", "half": "top"}],
806 |
807 | "109:0": ["stone_brick_stairs", {"facing": "east", "half": "bottom"}],
808 | "109:1": ["stone_brick_stairs", {"facing": "west", "half": "bottom"}],
809 | "109:2": ["stone_brick_stairs", {"facing": "south", "half": "bottom"}],
810 | "109:3": ["stone_brick_stairs", {"facing": "north", "half": "bottom"}],
811 | "109:4": ["stone_brick_stairs", {"facing": "east", "half": "top"}],
812 | "109:5": ["stone_brick_stairs", {"facing": "west", "half": "top"}],
813 | "109:6": ["stone_brick_stairs", {"facing": "south", "half": "top"}],
814 | "109:7": ["stone_brick_stairs", {"facing": "north", "half": "top"}],
815 |
816 | "110:0": ["mycelium", null],
817 | "111:0": ["lily_pad", null],
818 | "112:0": ["nether_bricks", null],
819 | "113:0": ["nether_brick_fence", null],
820 |
821 | "114:0": ["nether_brick_stairs", {"facing": "east", "half": "bottom"}],
822 | "114:1": ["nether_brick_stairs", {"facing": "west", "half": "bottom"}],
823 | "114:2": ["nether_brick_stairs", {"facing": "south", "half": "bottom"}],
824 | "114:3": ["nether_brick_stairs", {"facing": "north", "half": "bottom"}],
825 | "114:4": ["nether_brick_stairs", {"facing": "east", "half": "top"}],
826 | "114:5": ["nether_brick_stairs", {"facing": "west", "half": "top"}],
827 | "114:6": ["nether_brick_stairs", {"facing": "south", "half": "top"}],
828 | "114:7": ["nether_brick_stairs", {"facing": "north", "half": "top"}],
829 |
830 | "115:0": ["nether_wart", {"age": 0}],
831 | "115:1": ["nether_wart", {"age": 1}],
832 | "115:2": ["nether_wart", {"age": 2}],
833 | "115:3": ["nether_wart", {"age": 3}],
834 |
835 | "116:0": ["enchanting_table", null],
836 |
837 | "117:0": ["brewing_stand", {"has_bottle_0": false, "has_bottle_1": false, "has_bottle_2": false}],
838 | "117:1": ["brewing_stand", {"has_bottle_0": true, "has_bottle_1": false, "has_bottle_2": false}],
839 | "117:2": ["brewing_stand", {"has_bottle_0": false, "has_bottle_1": true, "has_bottle_2": false}],
840 | "117:3": ["brewing_stand", {"has_bottle_0": true, "has_bottle_1": true, "has_bottle_2": false}],
841 | "117:4": ["brewing_stand", {"has_bottle_0": false, "has_bottle_1": false, "has_bottle_2": true}],
842 | "117:5": ["brewing_stand", {"has_bottle_0": true, "has_bottle_1": false, "has_bottle_2": true}],
843 | "117:6": ["brewing_stand", {"has_bottle_0": false, "has_bottle_1": true, "has_bottle_2": true}],
844 | "117:7": ["brewing_stand", {"has_bottle_0": true, "has_bottle_1": true, "has_bottle_2": true}],
845 |
846 |
847 | "118:0": ["cauldron", {"level": 0}],
848 | "118:1": ["cauldron", {"level": 1}],
849 | "118:2": ["cauldron", {"level": 2}],
850 | "118:3": ["cauldron", {"level": 3}],
851 |
852 | "119:0": ["end_portal", null],
853 |
854 | "120:0": ["end_portal_frame", {"facing": "south", "eye": false}],
855 | "120:1": ["end_portal_frame", {"facing": "west", "eye": false}],
856 | "120:2": ["end_portal_frame", {"facing": "north", "eye": false}],
857 | "120:3": ["end_portal_frame", {"facing": "east", "eye": false}],
858 | "120:4": ["end_portal_frame", {"facing": "south", "eye": true}],
859 | "120:5": ["end_portal_frame", {"facing": "west", "eye": true}],
860 | "120:6": ["end_portal_frame", {"facing": "north", "eye": true}],
861 | "120:7": ["end_portal_frame", {"facing": "east", "eye": true}],
862 |
863 | "121:0": ["end_stone", null],
864 | "122:0": ["dragon_egg", null],
865 | "123:0": ["redstone_lamp", {"lit": false}],
866 | "124:0": ["redstone_lamp", {"lit": true}],
867 |
868 | "125:0": ["oak_slab", {"type": "double"}],
869 | "125:1": ["spruce_slab", {"type": "double"}],
870 | "125:2": ["birch_slab", {"type": "double"}],
871 | "125:3": ["jungle_slab", {"type": "double"}],
872 | "125:4": ["acacia_slab", {"type": "double"}],
873 | "125:5": ["dark_oak_slab", {"type": "double"}],
874 |
875 | "126:0": ["oak_slab", {"type": "bottom"}],
876 | "126:1": ["spruce_slab", {"type": "bottom"}],
877 | "126:2": ["birch_slab", {"type": "bottom"}],
878 | "126:3": ["jungle_slab", {"type": "bottom"}],
879 | "126:4": ["acacia_slab", {"type": "bottom"}],
880 | "126:5": ["dark_oak_slab", {"type": "bottom"}],
881 | "126:8": ["oak_slab", {"type": "top"}],
882 | "126:9": ["spruce_slab", {"type": "top"}],
883 | "126:10": ["birch_slab", {"type": "top"}],
884 | "126:11": ["jungle_slab", {"type": "top"}],
885 | "126:12": ["acacia_slab", {"type": "top"}],
886 | "126:13": ["dark_oak_slab", {"type": "top"}],
887 |
888 | "127:0": ["cocoa", {"facing": "north", "age": 0}],
889 | "127:1": ["cocoa", {"facing": "east", "age": 0}],
890 | "127:2": ["cocoa", {"facing": "south", "age": 0}],
891 | "127:3": ["cocoa", {"facing": "west", "age": 0}],
892 | "127:4": ["cocoa", {"facing": "north", "age": 1}],
893 | "127:5": ["cocoa", {"facing": "east", "age": 1}],
894 | "127:6": ["cocoa", {"facing": "south", "age": 1}],
895 | "127:7": ["cocoa", {"facing": "west", "age": 1}],
896 | "127:8": ["cocoa", {"facing": "north", "age": 2}],
897 | "127:9": ["cocoa", {"facing": "east", "age": 2}],
898 | "127:10": ["cocoa", {"facing": "south", "age": 2}],
899 | "127:11": ["cocoa", {"facing": "west", "age": 2}],
900 | "127:12": ["cocoa", {"facing": "north", "age": 3}],
901 | "127:13": ["cocoa", {"facing": "east", "age": 3}],
902 | "127:14": ["cocoa", {"facing": "south", "age": 3}],
903 | "127:15": ["cocoa", {"facing": "west", "age": 3}],
904 |
905 | "128:0": ["sandstone_stairs", {"facing": "east", "half": "bottom"}],
906 | "128:1": ["sandstone_stairs", {"facing": "west", "half": "bottom"}],
907 | "128:2": ["sandstone_stairs", {"facing": "south", "half": "bottom"}],
908 | "128:3": ["sandstone_stairs", {"facing": "north", "half": "bottom"}],
909 | "128:4": ["sandstone_stairs", {"facing": "east", "half": "top"}],
910 | "128:5": ["sandstone_stairs", {"facing": "west", "half": "top"}],
911 | "128:6": ["sandstone_stairs", {"facing": "south", "half": "top"}],
912 | "128:7": ["sandstone_stairs", {"facing": "north", "half": "top"}],
913 |
914 | "129:0": ["emerald_ore", null],
915 |
916 | "130:0": ["ender_chest", {"facing": "north"}],
917 | "130:1": ["ender_chest", {"facing": "north"}],
918 | "130:2": ["ender_chest", {"facing": "north"}],
919 | "130:3": ["ender_chest", {"facing": "south"}],
920 | "130:4": ["ender_chest", {"facing": "west"}],
921 | "130:5": ["ender_chest", {"facing": "east"}],
922 |
923 | "131:0": ["tripwire_hook", {"facing": "south", "attached": false, "powered": false}],
924 | "131:1": ["tripwire_hook", {"facing": "west", "attached": false, "powered": false}],
925 | "131:2": ["tripwire_hook", {"facing": "north", "attached": false, "powered": false}],
926 | "131:3": ["tripwire_hook", {"facing": "east", "attached": false, "powered": false}],
927 | "131:4": ["tripwire_hook", {"facing": "south", "attached": true, "powered": false}],
928 | "131:5": ["tripwire_hook", {"facing": "west", "attached": true, "powered": false}],
929 | "131:6": ["tripwire_hook", {"facing": "north", "attached": true, "powered": false}],
930 | "131:7": ["tripwire_hook", {"facing": "east", "attached": true, "powered": false}],
931 | "131:8": ["tripwire_hook", {"facing": "south", "attached": false, "powered": true}],
932 | "131:9": ["tripwire_hook", {"facing": "west", "attached": false, "powered": true}],
933 | "131:10": ["tripwire_hook", {"facing": "north", "attached": false, "powered": true}],
934 | "131:11": ["tripwire_hook", {"facing": "east", "attached": false, "powered": true}],
935 | "131:12": ["tripwire_hook", {"facing": "south", "attached": true, "powered": true}],
936 | "131:13": ["tripwire_hook", {"facing": "west", "attached": true, "powered": true}],
937 | "131:14": ["tripwire_hook", {"facing": "north", "attached": true, "powered": true}],
938 | "131:15": ["tripwire_hook", {"facing": "east", "attached": true, "powered": true}],
939 |
940 | "132:0": ["tripwire", {"powered": false, "attached": false, "disarmed": false}],
941 | "132:1": ["tripwire", {"powered": true, "attached": false, "disarmed": false}],
942 | "132:4": ["tripwire", {"powered": false, "attached": true, "disarmed": false}],
943 | "132:5": ["tripwire", {"powered": true, "attached": true, "disarmed": false}],
944 | "132:8": ["tripwire", {"powered": false, "attached": false, "disarmed": true}],
945 | "132:9": ["tripwire", {"powered": true, "attached": false, "disarmed": true}],
946 | "132:12": ["tripwire", {"powered": false, "attached": true, "disarmed": true}],
947 | "132:13": ["tripwire", {"powered": true, "attached": true, "disarmed": true}],
948 |
949 | "133:0": ["emerald_block", null],
950 |
951 | "134:0": ["spruce_stairs", {"facing": "east", "half": "bottom"}],
952 | "134:1": ["spruce_stairs", {"facing": "west", "half": "bottom"}],
953 | "134:2": ["spruce_stairs", {"facing": "south", "half": "bottom"}],
954 | "134:3": ["spruce_stairs", {"facing": "north", "half": "bottom"}],
955 | "134:4": ["spruce_stairs", {"facing": "east", "half": "top"}],
956 | "134:5": ["spruce_stairs", {"facing": "west", "half": "top"}],
957 | "134:6": ["spruce_stairs", {"facing": "south", "half": "top"}],
958 | "134:7": ["spruce_stairs", {"facing": "north", "half": "top"}],
959 |
960 | "135:0": ["birch_stairs", {"facing": "east", "half": "bottom"}],
961 | "135:1": ["birch_stairs", {"facing": "west", "half": "bottom"}],
962 | "135:2": ["birch_stairs", {"facing": "south", "half": "bottom"}],
963 | "135:3": ["birch_stairs", {"facing": "north", "half": "bottom"}],
964 | "135:4": ["birch_stairs", {"facing": "east", "half": "top"}],
965 | "135:5": ["birch_stairs", {"facing": "west", "half": "top"}],
966 | "135:6": ["birch_stairs", {"facing": "south", "half": "top"}],
967 | "135:7": ["birch_stairs", {"facing": "north", "half": "top"}],
968 |
969 | "136:0": ["jungle_stairs", {"facing": "east", "half": "bottom"}],
970 | "136:1": ["jungle_stairs", {"facing": "west", "half": "bottom"}],
971 | "136:2": ["jungle_stairs", {"facing": "south", "half": "bottom"}],
972 | "136:3": ["jungle_stairs", {"facing": "north", "half": "bottom"}],
973 | "136:4": ["jungle_stairs", {"facing": "east", "half": "top"}],
974 | "136:5": ["jungle_stairs", {"facing": "west", "half": "top"}],
975 | "136:6": ["jungle_stairs", {"facing": "south", "half": "top"}],
976 | "136:7": ["jungle_stairs", {"facing": "north", "half": "top"}],
977 |
978 | "137:0": ["command_block", null],
979 | "138:0": ["beacon", null],
980 |
981 | "139:0": ["cobblestone_wall", null],
982 |
983 | "139:1": ["mossy_cobblestone_wall", null],
984 |
985 | "140:0": ["flower_pot", null],
986 | "140:1": ["potted_poppy", null],
987 | "140:2": ["potted_dandelion", null],
988 | "140:3": ["potted_oak_sapling", null],
989 | "140:4": ["potted_spruce_sapling", null],
990 | "140:5": ["potted_birch_sapling", null],
991 | "140:6": ["potted_jungle_sapling", null],
992 | "140:7": ["potted_red_mushroom", null],
993 | "140:8": ["potted_brown_mushroom", null],
994 | "140:9": ["potted_cactus", null],
995 | "140:10": ["potted_dead_bush", null],
996 | "140:11": ["potted_fern", null],
997 | "140:12": ["potted_acacia_sapling", null],
998 | "140:13": ["potted_dark_oak_sapling", null],
999 | "140:14": ["flower_pot", null],
1000 | "140:15": ["flower_pot", null],
1001 |
1002 | "141:0": ["carrots", {"age": 0}],
1003 | "141:1": ["carrots", {"age": 1}],
1004 | "141:2": ["carrots", {"age": 2}],
1005 | "141:3": ["carrots", {"age": 3}],
1006 | "141:4": ["carrots", {"age": 4}],
1007 | "141:5": ["carrots", {"age": 5}],
1008 | "141:6": ["carrots", {"age": 6}],
1009 | "141:7": ["carrots", {"age": 7}],
1010 |
1011 | "142:0": ["potatoes", {"age": 0}],
1012 | "142:1": ["potatoes", {"age": 1}],
1013 | "142:2": ["potatoes", {"age": 2}],
1014 | "142:3": ["potatoes", {"age": 3}],
1015 | "142:4": ["potatoes", {"age": 4}],
1016 | "142:5": ["potatoes", {"age": 5}],
1017 | "142:6": ["potatoes", {"age": 6}],
1018 | "142:7": ["potatoes", {"age": 7}],
1019 |
1020 | "143:0": ["oak_button", {"face": "ceiling", "powered": false}],
1021 | "143:1": ["oak_button", {"face": "wall", "facing": "east", "powered": false}],
1022 | "143:2": ["oak_button", {"face": "wall", "facing": "west", "powered": false}],
1023 | "143:3": ["oak_button", {"face": "wall", "facing": "south", "powered": false}],
1024 | "143:4": ["oak_button", {"face": "wall", "facing": "north", "powered": false}],
1025 | "143:5": ["oak_button", {"face": "floor", "powered": false}],
1026 | "143:8": ["oak_button", {"face": "ceiling", "powered": true}],
1027 | "143:9": ["oak_button", {"face": "wall", "facing": "east", "powered": true}],
1028 | "143:10": ["oak_button", {"face": "wall", "facing": "west", "powered": true}],
1029 | "143:11": ["oak_button", {"face": "wall", "facing": "south", "powered": true}],
1030 | "143:12": ["oak_button", {"face": "wall", "facing": "north", "powered": true}],
1031 | "143:13": ["oak_button", {"face": "floor", "powered": true}],
1032 |
1033 | "144:0": ["skull", null],
1034 | "144:1": ["skull", null],
1035 | "144:2": ["wall_skull", null],
1036 | "144:3": ["wall_skull", null],
1037 | "144:4": ["wall_skull", null],
1038 | "144:4": ["wall_skull", null],
1039 |
1040 | "145:0": ["anvil", {"facing": "south"}],
1041 | "145:1": ["anvil", {"facing": "west"}],
1042 | "145:2": ["anvil", {"facing": "north"}],
1043 | "145:3": ["anvil", {"facing": "east"}],
1044 | "145:4": ["chipped_anvil", {"facing": "south"}],
1045 | "145:5": ["chipped_anvil", {"facing": "west"}],
1046 | "145:6": ["chipped_anvil", {"facing": "north"}],
1047 | "145:7": ["chipped_anvil", {"facing": "east"}],
1048 | "145:8": ["damaged_anvil", {"facing": "south"}],
1049 | "145:9": ["damaged_anvil", {"facing": "west"}],
1050 | "145:10": ["damaged_anvil", {"facing": "north"}],
1051 | "145:11": ["damaged_anvil", {"facing": "east"}],
1052 |
1053 | "146:0": ["trapped_chest", {"facing": "north"}],
1054 | "146:1": ["trapped_chest", {"facing": "north"}],
1055 | "146:2": ["trapped_chest", {"facing": "north"}],
1056 | "146:3": ["trapped_chest", {"facing": "south"}],
1057 | "146:4": ["trapped_chest", {"facing": "west"}],
1058 | "146:5": ["trapped_chest", {"facing": "east"}],
1059 |
1060 | "147:0": ["light_weighted_pressure_plate", {"power": 0}],
1061 | "147:1": ["light_weighted_pressure_plate", {"power": 1}],
1062 | "147:2": ["light_weighted_pressure_plate", {"power": 2}],
1063 | "147:3": ["light_weighted_pressure_plate", {"power": 3}],
1064 | "147:4": ["light_weighted_pressure_plate", {"power": 4}],
1065 | "147:5": ["light_weighted_pressure_plate", {"power": 5}],
1066 | "147:6": ["light_weighted_pressure_plate", {"power": 6}],
1067 | "147:7": ["light_weighted_pressure_plate", {"power": 7}],
1068 | "147:8": ["light_weighted_pressure_plate", {"power": 8}],
1069 | "147:9": ["light_weighted_pressure_plate", {"power": 9}],
1070 | "147:10": ["light_weighted_pressure_plate", {"power": 10}],
1071 | "147:11": ["light_weighted_pressure_plate", {"power": 11}],
1072 | "147:12": ["light_weighted_pressure_plate", {"power": 12}],
1073 | "147:13": ["light_weighted_pressure_plate", {"power": 13}],
1074 | "147:14": ["light_weighted_pressure_plate", {"power": 14}],
1075 | "147:15": ["light_weighted_pressure_plate", {"power": 15}],
1076 |
1077 | "148:0": ["heavy_weighted_pressure_plate", {"power": 0}],
1078 | "148:1": ["heavy_weighted_pressure_plate", {"power": 1}],
1079 | "148:2": ["heavy_weighted_pressure_plate", {"power": 2}],
1080 | "148:3": ["heavy_weighted_pressure_plate", {"power": 3}],
1081 | "148:4": ["heavy_weighted_pressure_plate", {"power": 4}],
1082 | "148:5": ["heavy_weighted_pressure_plate", {"power": 5}],
1083 | "148:6": ["heavy_weighted_pressure_plate", {"power": 6}],
1084 | "148:7": ["heavy_weighted_pressure_plate", {"power": 7}],
1085 | "148:8": ["heavy_weighted_pressure_plate", {"power": 8}],
1086 | "148:9": ["heavy_weighted_pressure_plate", {"power": 9}],
1087 | "148:10": ["heavy_weighted_pressure_plate", {"power": 10}],
1088 | "148:11": ["heavy_weighted_pressure_plate", {"power": 11}],
1089 | "148:12": ["heavy_weighted_pressure_plate", {"power": 12}],
1090 | "148:13": ["heavy_weighted_pressure_plate", {"power": 13}],
1091 | "148:14": ["heavy_weighted_pressure_plate", {"power": 14}],
1092 | "148:15": ["heavy_weighted_pressure_plate", {"power": 15}],
1093 |
1094 | "149:0": ["comparator", {"facing": "south", "mode": "compare", "powered": false}],
1095 | "149:1": ["comparator", {"facing": "west", "mode": "compare", "powered": false}],
1096 | "149:2": ["comparator", {"facing": "north", "mode": "compare", "powered": false}],
1097 | "149:3": ["comparator", {"facing": "east", "mode": "compare", "powered": false}],
1098 | "149:4": ["comparator", {"facing": "south", "mode": "subtract", "powered": false}],
1099 | "149:5": ["comparator", {"facing": "west", "mode": "subtract", "powered": false}],
1100 | "149:6": ["comparator", {"facing": "north", "mode": "subtract", "powered": false}],
1101 | "149:7": ["comparator", {"facing": "east", "mode": "subtract", "powered": false}],
1102 |
1103 | "149:8": ["comparator", {"facing": "south", "mode": "compare", "powered": true}],
1104 | "149:9": ["comparator", {"facing": "west", "mode": "compare", "powered": true}],
1105 | "149:10": ["comparator", {"facing": "north", "mode": "compare", "powered": true}],
1106 | "149:11": ["comparator", {"facing": "east", "mode": "compare", "powered": true}],
1107 | "149:12": ["comparator", {"facing": "south", "mode": "subtract", "powered": true}],
1108 | "149:13": ["comparator", {"facing": "west", "mode": "subtract", "powered": true}],
1109 | "149:14": ["comparator", {"facing": "north", "mode": "subtract", "powered": true}],
1110 | "149:15": ["comparator", {"facing": "east", "mode": "subtract", "powered": true}],
1111 |
1112 | "150:0": ["comparator", {"facing": "south", "mode": "compare", "powered": true}],
1113 | "150:1": ["comparator", {"facing": "west", "mode": "compare", "powered": true}],
1114 | "150:2": ["comparator", {"facing": "north", "mode": "compare", "powered": true}],
1115 | "150:3": ["comparator", {"facing": "east", "mode": "compare", "powered": true}],
1116 | "150:4": ["comparator", {"facing": "south", "mode": "subtract", "powered": true}],
1117 | "150:5": ["comparator", {"facing": "west", "mode": "subtract", "powered": true}],
1118 | "150:6": ["comparator", {"facing": "north", "mode": "subtract", "powered": true}],
1119 | "150:7": ["comparator", {"facing": "east", "mode": "subtract", "powered": true}],
1120 |
1121 | "151:0": ["daylight_detector", {"power": 0, "inverted": false}],
1122 | "151:1": ["daylight_detector", {"power": 1, "inverted": false}],
1123 | "151:2": ["daylight_detector", {"power": 2, "inverted": false}],
1124 | "151:3": ["daylight_detector", {"power": 3, "inverted": false}],
1125 | "151:4": ["daylight_detector", {"power": 4, "inverted": false}],
1126 | "151:5": ["daylight_detector", {"power": 5, "inverted": false}],
1127 | "151:6": ["daylight_detector", {"power": 6, "inverted": false}],
1128 | "151:7": ["daylight_detector", {"power": 7, "inverted": false}],
1129 | "151:8": ["daylight_detector", {"power": 8, "inverted": false}],
1130 | "151:9": ["daylight_detector", {"power": 9, "inverted": false}],
1131 | "151:10": ["daylight_detector", {"power": 10, "inverted": false}],
1132 | "151:11": ["daylight_detector", {"power": 11, "inverted": false}],
1133 | "151:12": ["daylight_detector", {"power": 12, "inverted": false}],
1134 | "151:13": ["daylight_detector", {"power": 13, "inverted": false}],
1135 | "151:14": ["daylight_detector", {"power": 14, "inverted": false}],
1136 | "151:15": ["daylight_detector", {"power": 15, "inverted": false}],
1137 |
1138 |
1139 | "152:0": ["redstone_block", null],
1140 | "153:0": ["nether_quartz_ore", null],
1141 |
1142 | "154:0": ["hopper", {"facing": "down", "enabled": true}],
1143 | "154:2": ["hopper", {"facing": "north", "enabled": true}],
1144 | "154:3": ["hopper", {"facing": "south", "enabled": true}],
1145 | "154:4": ["hopper", {"facing": "west", "enabled": true}],
1146 | "154:5": ["hopper", {"facing": "east", "enabled": true}],
1147 | "154:8": ["hopper", {"facing": "down", "enabled": false}],
1148 | "154:10": ["hopper", {"facing": "north", "enabled": false}],
1149 | "154:11": ["hopper", {"facing": "south", "enabled": false}],
1150 | "154:12": ["hopper", {"facing": "west", "enabled": false}],
1151 | "154:13": ["hopper", {"facing": "east", "enabled": false}],
1152 |
1153 | "155:0": ["quartz_block", null],
1154 | "155:1": ["chiseled_quartz_block", null],
1155 | "155:2": ["quartz_pillar", {"axis": "y"}],
1156 | "155:3": ["quartz_pillar", {"axis": "x"}],
1157 | "155:4": ["quartz_pillar", {"axis": "z"}],
1158 |
1159 |
1160 |
1161 |
1162 | "156:0": ["quartz_stairs", {"facing": "east", "half": "bottom"}],
1163 | "156:1": ["quartz_stairs", {"facing": "west", "half": "bottom"}],
1164 | "156:2": ["quartz_stairs", {"facing": "south", "half": "bottom"}],
1165 | "156:3": ["quartz_stairs", {"facing": "north", "half": "bottom"}],
1166 | "156:4": ["quartz_stairs", {"facing": "east", "half": "top"}],
1167 | "156:5": ["quartz_stairs", {"facing": "west", "half": "top"}],
1168 | "156:6": ["quartz_stairs", {"facing": "south", "half": "top"}],
1169 | "156:7": ["quartz_stairs", {"facing": "north", "half": "top"}],
1170 |
1171 | "157:0": ["activator_rail", {"shape": "north_south", "powered": false}],
1172 | "157:1": ["activator_rail", {"shape": "east_west", "powered": false}],
1173 | "157:2": ["activator_rail", {"shape": "ascending_east", "powered": false}],
1174 | "157:3": ["activator_rail", {"shape": "ascending_west", "powered": false}],
1175 | "157:4": ["activator_rail", {"shape": "ascending_north", "powered": false}],
1176 | "157:5": ["activator_rail", {"shape": "ascending_south", "powered": false}],
1177 | "157:8": ["activator_rail", {"shape": "north_south", "powered": true}],
1178 | "157:9": ["activator_rail", {"shape": "east_west", "powered": true}],
1179 | "157:10": ["activator_rail", {"shape": "ascending_east", "powered": true}],
1180 | "157:11": ["activator_rail", {"shape": "ascending_west", "powered": true}],
1181 | "157:12": ["activator_rail", {"shape": "ascending_north", "powered": true}],
1182 | "157:13": ["activator_rail", {"shape": "ascending_south", "powered": true}],
1183 |
1184 | "158:0": ["dropper", {"facing": "down", "triggered": false}],
1185 | "158:1": ["dropper", {"facing": "up", "triggered": false}],
1186 | "158:2": ["dropper", {"facing": "north", "triggered": false}],
1187 | "158:3": ["dropper", {"facing": "south", "triggered": false}],
1188 | "158:4": ["dropper", {"facing": "west", "triggered": false}],
1189 | "158:5": ["dropper", {"facing": "east", "triggered": false}],
1190 | "158:8": ["dropper", {"facing": "down", "triggered": true}],
1191 | "158:9": ["dropper", {"facing": "up", "triggered": true}],
1192 | "158:10": ["dropper", {"facing": "north", "triggered": true}],
1193 | "158:11": ["dropper", {"facing": "south", "triggered": true}],
1194 | "158:12": ["dropper", {"facing": "west", "triggered": true}],
1195 | "158:13": ["dropper", {"facing": "east", "triggered": true}],
1196 |
1197 | "159:0": ["white_terracotta", null],
1198 | "159:1": ["orange_terracotta", null],
1199 | "159:2": ["magenta_terracotta", null],
1200 | "159:3": ["light_blue_terracotta", null],
1201 | "159:4": ["yellow_terracotta", null],
1202 | "159:5": ["lime_terracotta", null],
1203 | "159:6": ["pink_terracotta", null],
1204 | "159:7": ["gray_terracotta", null],
1205 | "159:8": ["light_gray_terracotta", null],
1206 | "159:9": ["cyan_terracotta", null],
1207 | "159:10": ["purple_terracotta", null],
1208 | "159:11": ["blue_terracotta", null],
1209 | "159:12": ["brown_terracotta", null],
1210 | "159:13": ["green_terracotta", null],
1211 | "159:14": ["red_terracotta", null],
1212 | "159:15": ["black_terracotta", null],
1213 |
1214 | "160:0": ["white_stained_glass_pane", null],
1215 | "160:1": ["orange_stained_glass_pane", null],
1216 | "160:2": ["magenta_stained_glass_pane", null],
1217 | "160:3": ["light_blue_stained_glass_pane", null],
1218 | "160:4": ["yellow_stained_glass_pane", null],
1219 | "160:5": ["lime_stained_glass_pane", null],
1220 | "160:6": ["pink_stained_glass_pane", null],
1221 | "160:7": ["gray_stained_glass_pane", null],
1222 | "160:8": ["light_gray_stained_glass_pane", null],
1223 | "160:9": ["cyan_stained_glass_pane", null],
1224 | "160:10": ["purple_stained_glass_pane", null],
1225 | "160:11": ["blue_stained_glass_pane", null],
1226 | "160:12": ["brown_stained_glass_pane", null],
1227 | "160:13": ["green_stained_glass_pane", null],
1228 | "160:14": ["red_stained_glass_pane", null],
1229 | "160:15": ["black_stained_glass_pane", null],
1230 |
1231 | "161:0": ["acacia_leaves", {"persistent": false}],
1232 | "161:1": ["dark_oak_leaves", {"persistent": false}],
1233 | "161:4": ["acacia_leaves", {"persistent": true}],
1234 | "161:5": ["dark_oak_leaves", {"persistent": true}],
1235 | "161:8": ["acacia_leaves", {"persistent": false}],
1236 | "161:9": ["dark_oak_leaves", {"persistent": false}],
1237 | "161:12": ["acacia_leaves", {"persistent": true}],
1238 | "161:13": ["dark_oak_leaves", {"persistent": true}],
1239 |
1240 | "162:0": ["acacia_log", {"axis": "y"}],
1241 | "162:1": ["dark_oak_log", {"axis": "y"}],
1242 | "162:4": ["acacia_log", {"axis": "x"}],
1243 | "162:5": ["dark_oak_log", {"axis": "x"}],
1244 | "162:8": ["acacia_log", {"axis": "z"}],
1245 | "162:9": ["dark_oak_log", {"axis": "z"}],
1246 | "162:12": ["acacia_log", null],
1247 | "162:13": ["dark_oak_log", null],
1248 |
1249 | "163:0": ["acacia_stairs", {"facing": "east", "half": "bottom"}],
1250 | "163:1": ["acacia_stairs", {"facing": "west", "half": "bottom"}],
1251 | "163:2": ["acacia_stairs", {"facing": "south", "half": "bottom"}],
1252 | "163:3": ["acacia_stairs", {"facing": "north", "half": "bottom"}],
1253 | "163:4": ["acacia_stairs", {"facing": "east", "half": "top"}],
1254 | "163:5": ["acacia_stairs", {"facing": "west", "half": "top"}],
1255 | "163:6": ["acacia_stairs", {"facing": "south", "half": "top"}],
1256 | "163:7": ["acacia_stairs", {"facing": "north", "half": "top"}],
1257 |
1258 | "164:0": ["dark_oak_stairs", {"facing": "east", "half": "bottom"}],
1259 | "164:1": ["dark_oak_stairs", {"facing": "west", "half": "bottom"}],
1260 | "164:2": ["dark_oak_stairs", {"facing": "south", "half": "bottom"}],
1261 | "164:3": ["dark_oak_stairs", {"facing": "north", "half": "bottom"}],
1262 | "164:4": ["dark_oak_stairs", {"facing": "east", "half": "top"}],
1263 | "164:5": ["dark_oak_stairs", {"facing": "west", "half": "top"}],
1264 | "164:6": ["dark_oak_stairs", {"facing": "south", "half": "top"}],
1265 | "164:7": ["dark_oak_stairs", {"facing": "north", "half": "top"}],
1266 |
1267 | "165:0": ["slime_block", null],
1268 | "166:0": ["barrier", null],
1269 |
1270 | "167:0": ["iron_trapdoor", {"facing": "north", "open": false, "half": "bottom"}],
1271 | "167:1": ["iron_trapdoor", {"facing": "south", "open": false, "half": "bottom"}],
1272 | "167:2": ["iron_trapdoor", {"facing": "west", "open": false, "half": "bottom"}],
1273 | "167:3": ["iron_trapdoor", {"facing": "east", "open": false, "half": "bottom"}],
1274 | "167:4": ["iron_trapdoor", {"facing": "north", "open": true, "half": "bottom"}],
1275 | "167:5": ["iron_trapdoor", {"facing": "south", "open": true, "half": "bottom"}],
1276 | "167:6": ["iron_trapdoor", {"facing": "west", "open": true, "half": "bottom"}],
1277 | "167:7": ["iron_trapdoor", {"facing": "east", "open": true, "half": "bottom"}],
1278 | "167:8": ["iron_trapdoor", {"facing": "north", "open": false, "half": "top"}],
1279 | "167:9": ["iron_trapdoor", {"facing": "south", "open": false, "half": "top"}],
1280 | "167:10": ["iron_trapdoor", {"facing": "west", "open": false, "half": "top"}],
1281 | "167:11": ["iron_trapdoor", {"facing": "east", "open": false, "half": "top"}],
1282 | "167:12": ["iron_trapdoor", {"facing": "north", "open": true, "half": "top"}],
1283 | "167:13": ["iron_trapdoor", {"facing": "south", "open": true, "half": "top"}],
1284 | "167:14": ["iron_trapdoor", {"facing": "west", "open": true, "half": "top"}],
1285 | "167:15": ["iron_trapdoor", {"facing": "east", "open": true, "half": "top"}],
1286 |
1287 | "168:0": ["prismarine", null],
1288 | "168:1": ["prismarine_bricks", null],
1289 | "168:2": ["dark_prismarine", null],
1290 | "169:0": ["sea_lantern", null],
1291 |
1292 | "170:0": ["hay_block", {"axis": "y"}],
1293 | "170:4": ["hay_block", {"axis": "x"}],
1294 | "170:8": ["hay_block", {"axis": "z"}],
1295 |
1296 | "171:0": ["white_carpet", null],
1297 | "171:1": ["orange_carpet", null],
1298 | "171:2": ["magenta_carpet", null],
1299 | "171:3": ["light_blue_carpet", null],
1300 | "171:4": ["yellow_carpet", null],
1301 | "171:5": ["lime_carpet", null],
1302 | "171:6": ["pink_carpet", null],
1303 | "171:7": ["gray_carpet", null],
1304 | "171:8": ["light_gray_carpet", null],
1305 | "171:9": ["cyan_carpet", null],
1306 | "171:10": ["purple_carpet", null],
1307 | "171:11": ["blue_carpet", null],
1308 | "171:12": ["brown_carpet", null],
1309 | "171:13": ["green_carpet", null],
1310 | "171:14": ["red_carpet", null],
1311 | "171:15": ["black_carpet", null],
1312 | "172:0": ["terracotta", null],
1313 | "173:0": ["coal_block", null],
1314 | "174:0": ["packed_ice", null],
1315 |
1316 | "175:0": ["sunflower", {"half": "lower"}],
1317 | "175:1": ["lilac", {"half": "lower"}],
1318 | "175:2": ["tall_grass", {"half": "lower"}],
1319 | "175:3": ["large_fern", {"half": "lower"}],
1320 | "175:4": ["rose_bush", {"half": "lower"}],
1321 | "175:5": ["peony", {"half": "lower"}],
1322 | "175:8": ["sunflower", {"half": "upper"}],
1323 | "175:9": ["lilac", {"half": "upper"}],
1324 | "175:10": ["tall_grass", {"half": "upper"}],
1325 | "175:11": ["large_fern", {"half": "upper"}],
1326 | "175:12": ["rose_bush", {"half": "upper"}],
1327 | "175:13": ["peony", {"half": "upper"}],
1328 |
1329 | "176:0": ["banner", {"rotation": 0}],
1330 | "176:1": ["banner", {"rotation": 1}],
1331 | "176:2": ["banner", {"rotation": 2}],
1332 | "176:3": ["banner", {"rotation": 3}],
1333 | "176:4": ["banner", {"rotation": 4}],
1334 | "176:5": ["banner", {"rotation": 5}],
1335 | "176:6": ["banner", {"rotation": 6}],
1336 | "176:7": ["banner", {"rotation": 7}],
1337 | "176:8": ["banner", {"rotation": 8}],
1338 | "176:9": ["banner", {"rotation": 9}],
1339 | "176:10": ["banner", {"rotation": 10}],
1340 | "176:11": ["banner", {"rotation": 11}],
1341 | "176:12": ["banner", {"rotation": 12}],
1342 | "176:13": ["banner", {"rotation": 13}],
1343 | "176:14": ["banner", {"rotation": 14}],
1344 | "176:15": ["banner", {"rotation": 15}],
1345 |
1346 | "177:2": ["wall_banner", {"facing": "north"}],
1347 | "177:3": ["wall_banner", {"facing": "south"}],
1348 | "177:4": ["wall_banner", {"facing": "west"}],
1349 | "177:5": ["wall_banner", {"facing": "east"}],
1350 |
1351 | "178:0": ["daylight_detector", {"power": 0, "inverted": true}],
1352 | "178:1": ["daylight_detector", {"power": 1, "inverted": true}],
1353 | "178:2": ["daylight_detector", {"power": 2, "inverted": true}],
1354 | "178:3": ["daylight_detector", {"power": 3, "inverted": true}],
1355 | "178:4": ["daylight_detector", {"power": 4, "inverted": true}],
1356 | "178:5": ["daylight_detector", {"power": 5, "inverted": true}],
1357 | "178:6": ["daylight_detector", {"power": 6, "inverted": true}],
1358 | "178:7": ["daylight_detector", {"power": 7, "inverted": true}],
1359 | "178:8": ["daylight_detector", {"power": 8, "inverted": true}],
1360 | "178:9": ["daylight_detector", {"power": 9, "inverted": true}],
1361 | "178:10": ["daylight_detector", {"power": 10, "inverted": true}],
1362 | "178:11": ["daylight_detector", {"power": 11, "inverted": true}],
1363 | "178:12": ["daylight_detector", {"power": 12, "inverted": true}],
1364 | "178:13": ["daylight_detector", {"power": 13, "inverted": true}],
1365 | "178:14": ["daylight_detector", {"power": 14, "inverted": true}],
1366 | "178:15": ["daylight_detector", {"power": 15, "inverted": true}],
1367 |
1368 | "179:0": ["red_sandstone", null],
1369 | "179:1": ["chiseled_red_sandstone", null],
1370 | "179:2": ["cut_red_sandstone", null],
1371 |
1372 | "180:0": ["red_sandstone_stairs", {"facing": "east", "half": "bottom"}],
1373 | "180:1": ["red_sandstone_stairs", {"facing": "west", "half": "bottom"}],
1374 | "180:2": ["red_sandstone_stairs", {"facing": "south", "half": "bottom"}],
1375 | "180:3": ["red_sandstone_stairs", {"facing": "north", "half": "bottom"}],
1376 | "180:4": ["red_sandstone_stairs", {"facing": "east", "half": "top"}],
1377 | "180:5": ["red_sandstone_stairs", {"facing": "west", "half": "top"}],
1378 | "180:6": ["red_sandstone_stairs", {"facing": "south", "half": "top"}],
1379 | "180:7": ["red_sandstone_stairs", {"facing": "north", "half": "top"}],
1380 |
1381 | "181:0": ["red_sandstone", null],
1382 | "181:1": ["purpur_block", null],
1383 | "181:2": ["prismarine", null],
1384 | "181:3": ["prismarine_bricks", null],
1385 | "181:4": ["dark_prismarine", null],
1386 |
1387 | "182:0": ["red_sandstone_slab", {"type": "bottom"}],
1388 | "182:8": ["red_sandstone_slab", {"type": "top"}],
1389 |
1390 | "183:0": ["spruce_fence_gate", {"facing": "south", "open": false, "powered": false}],
1391 | "183:1": ["spruce_fence_gate", {"facing": "west", "open": false, "powered": false}],
1392 | "183:2": ["spruce_fence_gate", {"facing": "north", "open": false, "powered": false}],
1393 | "183:3": ["spruce_fence_gate", {"facing": "east", "open": false, "powered": false}],
1394 | "183:4": ["spruce_fence_gate", {"facing": "south", "open": true, "powered": false}],
1395 | "183:5": ["spruce_fence_gate", {"facing": "west", "open": true, "powered": false}],
1396 | "183:6": ["spruce_fence_gate", {"facing": "north", "open": true, "powered": false}],
1397 | "183:7": ["spruce_fence_gate", {"facing": "east", "open": true, "powered": false}],
1398 | "183:8": ["spruce_fence_gate", {"facing": "south", "open": false, "powered": true}],
1399 | "183:9": ["spruce_fence_gate", {"facing": "west", "open": false, "powered": true}],
1400 | "183:10": ["spruce_fence_gate", {"facing": "north", "open": false, "powered": true}],
1401 | "183:11": ["spruce_fence_gate", {"facing": "east", "open": false, "powered": true}],
1402 | "183:12": ["spruce_fence_gate", {"facing": "south", "open": true, "powered": true}],
1403 | "183:13": ["spruce_fence_gate", {"facing": "west", "open": true, "powered": true}],
1404 | "183:14": ["spruce_fence_gate", {"facing": "north", "open": true, "powered": true}],
1405 | "183:15": ["spruce_fence_gate", {"facing": "east", "open": true, "powered": true}],
1406 |
1407 | "184:0": ["birch_fence_gate", {"facing": "south", "open": false, "powered": false}],
1408 | "184:1": ["birch_fence_gate", {"facing": "west", "open": false, "powered": false}],
1409 | "184:2": ["birch_fence_gate", {"facing": "north", "open": false, "powered": false}],
1410 | "184:3": ["birch_fence_gate", {"facing": "east", "open": false, "powered": false}],
1411 | "184:4": ["birch_fence_gate", {"facing": "south", "open": true, "powered": false}],
1412 | "184:5": ["birch_fence_gate", {"facing": "west", "open": true, "powered": false}],
1413 | "184:6": ["birch_fence_gate", {"facing": "north", "open": true, "powered": false}],
1414 | "184:7": ["birch_fence_gate", {"facing": "east", "open": true, "powered": false}],
1415 | "184:8": ["birch_fence_gate", {"facing": "south", "open": false, "powered": true}],
1416 | "184:9": ["birch_fence_gate", {"facing": "west", "open": false, "powered": true}],
1417 | "184:10": ["birch_fence_gate", {"facing": "north", "open": false, "powered": true}],
1418 | "184:11": ["birch_fence_gate", {"facing": "east", "open": false, "powered": true}],
1419 | "184:12": ["birch_fence_gate", {"facing": "south", "open": true, "powered": true}],
1420 | "184:13": ["birch_fence_gate", {"facing": "west", "open": true, "powered": true}],
1421 | "184:14": ["birch_fence_gate", {"facing": "north", "open": true, "powered": true}],
1422 | "184:15": ["birch_fence_gate", {"facing": "east", "open": true, "powered": true}],
1423 |
1424 | "185:0": ["jungle_fence_gate", {"facing": "south", "open": false, "powered": false}],
1425 | "185:1": ["jungle_fence_gate", {"facing": "west", "open": false, "powered": false}],
1426 | "185:2": ["jungle_fence_gate", {"facing": "north", "open": false, "powered": false}],
1427 | "185:3": ["jungle_fence_gate", {"facing": "east", "open": false, "powered": false}],
1428 | "185:4": ["jungle_fence_gate", {"facing": "south", "open": true, "powered": false}],
1429 | "185:5": ["jungle_fence_gate", {"facing": "west", "open": true, "powered": false}],
1430 | "185:6": ["jungle_fence_gate", {"facing": "north", "open": true, "powered": false}],
1431 | "185:7": ["jungle_fence_gate", {"facing": "east", "open": true, "powered": false}],
1432 | "185:8": ["jungle_fence_gate", {"facing": "west", "open": false, "powered": true}],
1433 | "185:9": ["jungle_fence_gate", {"facing": "west", "open": false, "powered": true}],
1434 | "185:10": ["jungle_fence_gate", {"facing": "north", "open": false, "powered": true}],
1435 | "185:11": ["jungle_fence_gate", {"facing": "east", "open": false, "powered": true}],
1436 | "185:12": ["jungle_fence_gate", {"facing": "south", "open": true, "powered": true}],
1437 | "185:13": ["jungle_fence_gate", {"facing": "west", "open": true, "powered": true}],
1438 | "185:14": ["jungle_fence_gate", {"facing": "north", "open": true, "powered": true}],
1439 | "185:15": ["jungle_fence_gate", {"facing": "east", "open": true, "powered": true}],
1440 |
1441 | "186:0": ["dark_oak_fence_gate", {"facing": "south", "open": false, "powered": false}],
1442 | "186:1": ["dark_oak_fence_gate", {"facing": "west", "open": false, "powered": false}],
1443 | "186:2": ["dark_oak_fence_gate", {"facing": "north", "open": false, "powered": false}],
1444 | "186:3": ["dark_oak_fence_gate", {"facing": "east", "open": false, "powered": false}],
1445 | "186:4": ["dark_oak_fence_gate", {"facing": "south", "open": true, "powered": false}],
1446 | "186:5": ["dark_oak_fence_gate", {"facing": "west", "open": true, "powered": false}],
1447 | "186:6": ["dark_oak_fence_gate", {"facing": "north", "open": true, "powered": false}],
1448 | "186:7": ["dark_oak_fence_gate", {"facing": "east", "open": true, "powered": false}],
1449 | "186:8": ["dark_oak_fence_gate", {"facing": "south", "open": false, "powered": true}],
1450 | "186:9": ["dark_oak_fence_gate", {"facing": "west", "open": false, "powered": true}],
1451 | "186:10": ["dark_oak_fence_gate", {"facing": "north", "open": false, "powered": true}],
1452 | "186:11": ["dark_oak_fence_gate", {"facing": "east", "open": false, "powered": true}],
1453 | "186:12": ["dark_oak_fence_gate", {"facing": "south", "open": true, "powered": true}],
1454 | "186:13": ["dark_oak_fence_gate", {"facing": "west", "open": true, "powered": true}],
1455 | "186:14": ["dark_oak_fence_gate", {"facing": "north", "open": true, "powered": true}],
1456 | "186:15": ["dark_oak_fence_gate", {"facing": "east", "open": true, "powered": true}],
1457 |
1458 | "187:0": ["acacia_fence_gate", {"facing": "south", "open": false, "powered": false}],
1459 | "187:1": ["acacia_fence_gate", {"facing": "west", "open": false, "powered": false}],
1460 | "187:2": ["acacia_fence_gate", {"facing": "north", "open": false, "powered": false}],
1461 | "187:3": ["acacia_fence_gate", {"facing": "east", "open": false, "powered": false}],
1462 | "187:4": ["acacia_fence_gate", {"facing": "south", "open": true, "powered": false}],
1463 | "187:5": ["acacia_fence_gate", {"facing": "west", "open": true, "powered": false}],
1464 | "187:6": ["acacia_fence_gate", {"facing": "north", "open": true, "powered": false}],
1465 | "187:7": ["acacia_fence_gate", {"facing": "east", "open": true, "powered": false}],
1466 | "187:8": ["acacia_fence_gate", {"facing": "south", "open": false, "powered": true}],
1467 | "187:9": ["acacia_fence_gate", {"facing": "west", "open": false, "powered": true}],
1468 | "187:10": ["acacia_fence_gate", {"facing": "north", "open": false, "powered": true}],
1469 | "187:11": ["acacia_fence_gate", {"facing": "east", "open": false, "powered": true}],
1470 | "187:12": ["acacia_fence_gate", {"facing": "south", "open": true, "powered": true}],
1471 | "187:13": ["acacia_fence_gate", {"facing": "west", "open": true, "powered": true}],
1472 | "187:14": ["acacia_fence_gate", {"facing": "north", "open": true, "powered": true}],
1473 | "187:15": ["acacia_fence_gate", {"facing": "east", "open": true, "powered": true}],
1474 |
1475 | "188:0": ["spruce_fence", null],
1476 | "189:0": ["birch_fence", null],
1477 | "190:0": ["jungle_fence", null],
1478 | "191:0": ["dark_oak_fence", null],
1479 | "192:0": ["acacia_fence", null],
1480 |
1481 | "193:0": ["spruce_door", {"half": "lower", "facing": "east", "open": false}],
1482 | "193:1": ["spruce_door", {"half": "lower", "facing": "south", "open": false}],
1483 | "193:2": ["spruce_door", {"half": "lower", "facing": "west", "open": false}],
1484 | "193:3": ["spruce_door", {"half": "lower", "facing": "north", "open": false}],
1485 | "193:4": ["spruce_door", {"half": "lower", "facing": "east", "open": true}],
1486 | "193:5": ["spruce_door", {"half": "lower", "facing": "south", "open": true}],
1487 | "193:6": ["spruce_door", {"half": "lower", "facing": "west", "open": true}],
1488 | "193:7": ["spruce_door", {"half": "lower", "facing": "north", "open": true}],
1489 |
1490 | "193:8": ["spruce_door", {"half": "upper", "hinge": "left", "powered": false}],
1491 | "193:9": ["spruce_door", {"half": "upper", "hinge": "right", "powered": false}],
1492 | "193:10": ["spruce_door", {"half": "upper", "hinge": "left", "powered": true}],
1493 | "193:11": ["spruce_door", {"half": "upper", "hinge": "right", "powered": true}],
1494 |
1495 | "194:0": ["birch_door", {"half": "lower", "facing": "east", "open": false}],
1496 | "194:1": ["birch_door", {"half": "lower", "facing": "south", "open": false}],
1497 | "194:2": ["birch_door", {"half": "lower", "facing": "west", "open": false}],
1498 | "194:3": ["birch_door", {"half": "lower", "facing": "north", "open": false}],
1499 | "194:4": ["birch_door", {"half": "lower", "facing": "east", "open": true}],
1500 | "194:5": ["birch_door", {"half": "lower", "facing": "south", "open": true}],
1501 | "194:6": ["birch_door", {"half": "lower", "facing": "west", "open": true}],
1502 | "194:7": ["birch_door", {"half": "lower", "facing": "north", "open": true}],
1503 |
1504 | "194:8": ["birch_door", {"half": "upper", "hinge": "left", "powered": false}],
1505 | "194:9": ["birch_door", {"half": "upper", "hinge": "right", "powered": false}],
1506 | "194:10": ["birch_door", {"half": "upper", "hinge": "left", "powered": true}],
1507 | "194:11": ["birch_door", {"half": "upper", "hinge": "right", "powered": true}],
1508 |
1509 | "195:0": ["jungle_door", {"half": "lower", "facing": "east", "open": false}],
1510 | "195:1": ["jungle_door", {"half": "lower", "facing": "south", "open": false}],
1511 | "195:2": ["jungle_door", {"half": "lower", "facing": "west", "open": false}],
1512 | "195:3": ["jungle_door", {"half": "lower", "facing": "north", "open": false}],
1513 | "195:4": ["jungle_door", {"half": "lower", "facing": "east", "open": true}],
1514 | "195:5": ["jungle_door", {"half": "lower", "facing": "south", "open": true}],
1515 | "195:6": ["jungle_door", {"half": "lower", "facing": "west", "open": true}],
1516 | "195:7": ["jungle_door", {"half": "lower", "facing": "north", "open": true}],
1517 |
1518 | "195:8": ["jungle_door", {"half": "upper", "hinge": "left", "powered": false}],
1519 | "195:9": ["jungle_door", {"half": "upper", "hinge": "right", "powered": false}],
1520 | "195:10": ["jungle_door", {"half": "upper", "hinge": "left", "powered": true}],
1521 | "195:11": ["jungle_door", {"half": "upper", "hinge": "right", "powered": true}],
1522 |
1523 | "196:0": ["acacia_door", {"half": "lower", "facing": "east", "open": false}],
1524 | "196:1": ["acacia_door", {"half": "lower", "facing": "south", "open": false}],
1525 | "196:2": ["acacia_door", {"half": "lower", "facing": "west", "open": false}],
1526 | "196:3": ["acacia_door", {"half": "lower", "facing": "north", "open": false}],
1527 | "196:4": ["acacia_door", {"half": "lower", "facing": "east", "open": true}],
1528 | "196:5": ["acacia_door", {"half": "lower", "facing": "south", "open": true}],
1529 | "196:6": ["acacia_door", {"half": "lower", "facing": "west", "open": true}],
1530 | "196:7": ["acacia_door", {"half": "lower", "facing": "north", "open": true}],
1531 |
1532 | "196:8": ["acacia_door", {"half": "upper", "hinge": "left", "powered": false}],
1533 | "196:9": ["acacia_door", {"half": "upper", "hinge": "right", "powered": false}],
1534 | "196:10": ["acacia_door", {"half": "upper", "hinge": "left", "powered": true}],
1535 | "196:11": ["acacia_door", {"half": "upper", "hinge": "right", "powered": true}],
1536 |
1537 | "197:0": ["dark_oak_door", {"half": "lower", "facing": "east", "open": false}],
1538 | "197:1": ["dark_oak_door", {"half": "lower", "facing": "south", "open": false}],
1539 | "197:2": ["dark_oak_door", {"half": "lower", "facing": "west", "open": false}],
1540 | "197:3": ["dark_oak_door", {"half": "lower", "facing": "north", "open": false}],
1541 | "197:4": ["dark_oak_door", {"half": "lower", "facing": "east", "open": true}],
1542 | "197:5": ["dark_oak_door", {"half": "lower", "facing": "south", "open": true}],
1543 | "197:6": ["dark_oak_door", {"half": "lower", "facing": "west", "open": true}],
1544 | "197:7": ["dark_oak_door", {"half": "lower", "facing": "north", "open": true}],
1545 |
1546 | "197:8": ["dark_oak_door", {"half": "upper", "hinge": "left", "powered": false}],
1547 | "197:9": ["dark_oak_door", {"half": "upper", "hinge": "right", "powered": false}],
1548 | "197:10": ["dark_oak_door", {"half": "upper", "hinge": "left", "powered": true}],
1549 | "197:11": ["dark_oak_door", {"half": "upper", "hinge": "right", "powered": true}],
1550 |
1551 | "198:0": ["end_rod", {"facing": "down"}],
1552 | "198:1": ["end_rod", {"facing": "up"}],
1553 | "198:2": ["end_rod", {"facing": "north"}],
1554 | "198:3": ["end_rod", {"facing": "south"}],
1555 | "198:4": ["end_rod", {"facing": "west"}],
1556 | "198:5": ["end_rod", {"facing": "east"}],
1557 |
1558 | "199:0": ["chorus_plant", null],
1559 |
1560 | "200:0": ["chorus_flower", {"age": 0}],
1561 | "200:1": ["chorus_flower", {"age": 1}],
1562 | "200:2": ["chorus_flower", {"age": 2}],
1563 | "200:3": ["chorus_flower", {"age": 3}],
1564 | "200:4": ["chorus_flower", {"age": 4}],
1565 | "200:5": ["chorus_flower", {"age": 5}],
1566 |
1567 | "201:0": ["purpur_block", null],
1568 |
1569 | "202:0": ["purpur_pillar", {"axis": "y"}],
1570 | "202:4": ["purpur_pillar", {"axis": "x"}],
1571 | "202:8": ["purpur_pillar", {"axis": "z"}],
1572 |
1573 | "203:0": ["purpur_stairs", {"facing": "east", "half": "bottom"}],
1574 | "203:1": ["purpur_stairs", {"facing": "west", "half": "bottom"}],
1575 | "203:2": ["purpur_stairs", {"facing": "south", "half": "bottom"}],
1576 | "203:3": ["purpur_stairs", {"facing": "north", "half": "bottom"}],
1577 | "203:4": ["purpur_stairs", {"facing": "east", "half": "top"}],
1578 | "203:5": ["purpur_stairs", {"facing": "west", "half": "top"}],
1579 | "203:6": ["purpur_stairs", {"facing": "south", "half": "top"}],
1580 | "203:7": ["purpur_stairs", {"facing": "north", "half": "top"}],
1581 |
1582 | "204:0": ["purpur_slab", {"type": "double"}],
1583 |
1584 | "205:0": ["purpur_slab", {"type": "bottom"}],
1585 | "205:8": ["purpur_slab", {"type": "top"}],
1586 |
1587 | "206:0": ["end_stone_bricks", null],
1588 |
1589 | "207:0": ["beetroots", {"age": 0}],
1590 | "207:1": ["beetroots", {"age": 1}],
1591 | "207:2": ["beetroots", {"age": 2}],
1592 | "207:3": ["beetroots", {"age": 3}],
1593 |
1594 | "208:0": ["grass_path", null],
1595 | "209:0": ["end_gateway", null],
1596 | "210:0": ["repeating_command_block", null],
1597 | "211:0": ["chain_command_block", null],
1598 | "212:0": ["frosted_ice", null],
1599 | "213:0": ["magma_block", null],
1600 | "214:0": ["nether_wart_block", null],
1601 |
1602 | "216:0": ["bone_block", {"axis": "y"}],
1603 | "216:4": ["bone_block", {"axis": "x"}],
1604 | "216:8": ["bone_block", {"axis": "z"}],
1605 |
1606 | "215:0": ["red_nether_bricks", null],
1607 | "217:0": ["structure_void", null],
1608 |
1609 | "218:0": ["observer", {"facing": "down", "powered": false}],
1610 | "218:1": ["observer", {"facing": "up", "powered": false}],
1611 | "218:2": ["observer", {"facing": "north", "powered": false}],
1612 | "218:3": ["observer", {"facing": "south", "powered": false}],
1613 | "218:4": ["observer", {"facing": "west", "powered": false}],
1614 | "218:5": ["observer", {"facing": "east", "powered": false}],
1615 | "218:6": ["observer", {"facing": "down", "powered": true}],
1616 | "218:7": ["observer", {"facing": "up", "powered": true}],
1617 | "218:8": ["observer", {"facing": "north", "powered": true}],
1618 | "218:9": ["observer", {"facing": "south", "powered": true}],
1619 | "218:10": ["observer", {"facing": "west", "powered": true}],
1620 | "218:11": ["observer", {"facing": "east", "powered": true}],
1621 |
1622 | "219:0": ["white_shulker_box", {"facing": "down"}],
1623 | "219:1": ["white_shulker_box", {"facing": "up"}],
1624 | "219:2": ["white_shulker_box", {"facing": "north"}],
1625 | "219:3": ["white_shulker_box", {"facing": "south"}],
1626 | "219:4": ["white_shulker_box", {"facing": "west"}],
1627 | "219:5": ["white_shulker_box", {"facing": "east"}],
1628 |
1629 | "220:0": ["orange_shulker_box", {"facing": "down"}],
1630 | "220:1": ["orange_shulker_box", {"facing": "up"}],
1631 | "220:2": ["orange_shulker_box", {"facing": "north"}],
1632 | "220:3": ["orange_shulker_box", {"facing": "south"}],
1633 | "220:4": ["orange_shulker_box", {"facing": "west"}],
1634 | "220:5": ["orange_shulker_box", {"facing": "east"}],
1635 |
1636 | "221:0": ["magenta_shulker_box", {"facing": "down"}],
1637 | "221:1": ["magenta_shulker_box", {"facing": "up"}],
1638 | "221:2": ["magenta_shulker_box", {"facing": "north"}],
1639 | "221:3": ["magenta_shulker_box", {"facing": "south"}],
1640 | "221:4": ["magenta_shulker_box", {"facing": "west"}],
1641 | "221:5": ["magenta_shulker_box", {"facing": "east"}],
1642 |
1643 | "222:0": ["light_blue_shulker_box", {"facing": "down"}],
1644 | "222:1": ["light_blue_shulker_box", {"facing": "up"}],
1645 | "222:2": ["light_blue_shulker_box", {"facing": "north"}],
1646 | "222:3": ["light_blue_shulker_box", {"facing": "south"}],
1647 | "222:4": ["light_blue_shulker_box", {"facing": "west"}],
1648 | "222:5": ["light_blue_shulker_box", {"facing": "east"}],
1649 |
1650 | "223:0": ["yellow_shulker_box", {"facing": "down"}],
1651 | "223:1": ["yellow_shulker_box", {"facing": "up"}],
1652 | "223:2": ["yellow_shulker_box", {"facing": "north"}],
1653 | "223:3": ["yellow_shulker_box", {"facing": "south"}],
1654 | "223:4": ["yellow_shulker_box", {"facing": "west"}],
1655 | "223:5": ["yellow_shulker_box", {"facing": "east"}],
1656 |
1657 | "224:0": ["lime_shulker_box", {"facing": "down"}],
1658 | "224:1": ["lime_shulker_box", {"facing": "up"}],
1659 | "224:2": ["lime_shulker_box", {"facing": "north"}],
1660 | "224:3": ["lime_shulker_box", {"facing": "south"}],
1661 | "224:4": ["lime_shulker_box", {"facing": "west"}],
1662 | "224:5": ["lime_shulker_box", {"facing": "east"}],
1663 |
1664 | "225:0": ["pink_shulker_box", {"facing": "down"}],
1665 | "225:1": ["pink_shulker_box", {"facing": "up"}],
1666 | "225:2": ["pink_shulker_box", {"facing": "north"}],
1667 | "225:3": ["pink_shulker_box", {"facing": "south"}],
1668 | "225:4": ["pink_shulker_box", {"facing": "west"}],
1669 | "225:5": ["pink_shulker_box", {"facing": "east"}],
1670 |
1671 | "226:0": ["gray_shulker_box", {"facing": "down"}],
1672 | "226:1": ["gray_shulker_box", {"facing": "up"}],
1673 | "226:2": ["gray_shulker_box", {"facing": "north"}],
1674 | "226:3": ["gray_shulker_box", {"facing": "south"}],
1675 | "226:4": ["gray_shulker_box", {"facing": "west"}],
1676 | "226:5": ["gray_shulker_box", {"facing": "east"}],
1677 |
1678 | "227:0": ["light_gray_shulker_box", {"facing": "down"}],
1679 | "227:1": ["light_gray_shulker_box", {"facing": "up"}],
1680 | "227:2": ["light_gray_shulker_box", {"facing": "north"}],
1681 | "227:3": ["light_gray_shulker_box", {"facing": "south"}],
1682 | "227:4": ["light_gray_shulker_box", {"facing": "west"}],
1683 | "227:5": ["light_gray_shulker_box", {"facing": "east"}],
1684 |
1685 | "228:0": ["cyan_shulker_box", { "facing": "down"}],
1686 | "228:1": ["cyan_shulker_box", {"facing": "up"}],
1687 | "228:2": ["cyan_shulker_box", {"facing": "north"}],
1688 | "228:3": ["cyan_shulker_box", {"facing": "south"}],
1689 | "228:4": ["cyan_shulker_box", {"facing": "west"}],
1690 | "228:5": ["cyan_shulker_box", {"facing": "east"}],
1691 |
1692 | "229:0": ["purple_shulker_box", {"facing": "down"}],
1693 | "229:1": ["purple_shulker_box", {"facing": "up"}],
1694 | "229:2": ["purple_shulker_box", {"facing": "north"}],
1695 | "229:3": ["purple_shulker_box", {"facing": "south"}],
1696 | "229:4": ["purple_shulker_box", {"facing": "west"}],
1697 | "229:5": ["purple_shulker_box", {"facing": "east"}],
1698 |
1699 | "230:0": ["blue_shulker_box", {"facing": "down"}],
1700 | "230:1": ["blue_shulker_box", {"facing": "up"}],
1701 | "230:2": ["blue_shulker_box", {"facing": "north"}],
1702 | "230:3": ["blue_shulker_box", {"facing": "south"}],
1703 | "230:4": ["blue_shulker_box", {"facing": "west"}],
1704 | "230:5": ["blue_shulker_box", {"facing": "east"}],
1705 |
1706 | "231:0": ["brown_shulker_box", {"facing": "down"}],
1707 | "231:1": ["brown_shulker_box", {"facing": "up"}],
1708 | "231:2": ["brown_shulker_box", {"facing": "north"}],
1709 | "231:3": ["brown_shulker_box", {"facing": "south"}],
1710 | "231:4": ["brown_shulker_box", {"facing": "west"}],
1711 | "231:5": ["brown_shulker_box", {"facing": "east"}],
1712 |
1713 | "232:0": ["green_shulker_box", {"facing": "down"}],
1714 | "232:1": ["green_shulker_box", {"facing": "up"}],
1715 | "232:2": ["green_shulker_box", {"facing": "north"}],
1716 | "232:3": ["green_shulker_box", {"facing": "south"}],
1717 | "232:4": ["green_shulker_box", {"facing": "west"}],
1718 | "232:5": ["green_shulker_box", {"facing": "east"}],
1719 |
1720 | "233:0": ["red_shulker_box", {"facing": "down"}],
1721 | "233:1": ["red_shulker_box", {"facing": "up"}],
1722 | "233:2": ["red_shulker_box", {"facing": "north"}],
1723 | "233:3": ["red_shulker_box", {"facing": "south"}],
1724 | "233:4": ["red_shulker_box", {"facing": "west"}],
1725 | "233:5": ["red_shulker_box", {"facing": "east"}],
1726 |
1727 | "234:0": ["black_shulker_box", {"facing": "up"}],
1728 | "233:1": ["black_shulker_box", {"facing": "up"}],
1729 | "234:2": ["black_shulker_box", {"facing": "north"}],
1730 | "234:3": ["black_shulker_box", {"facing": "south"}],
1731 | "234:4": ["black_shulker_box", {"facing": "west"}],
1732 | "234:5": ["black_shulker_box", {"facing": "east"}],
1733 |
1734 |
1735 | "235:0": ["white_glazed_terracotta", {"facing": "south"}],
1736 | "235:1": ["white_glazed_terracotta", {"facing": "west"}],
1737 | "235:2": ["white_glazed_terracotta", {"facing": "north"}],
1738 | "235:3": ["white_glazed_terracotta", {"facing": "east"}],
1739 |
1740 | "236:0": ["orange_glazed_terracotta", {"facing": "south"}],
1741 | "236:1": ["orange_glazed_terracotta", {"facing": "west"}],
1742 | "236:2": ["orange_glazed_terracotta", {"facing": "north"}],
1743 | "236:3": ["orange_glazed_terracotta", {"facing": "east"}],
1744 |
1745 | "237:0": ["magenta_glazed_terracotta", {"facing": "south"}],
1746 | "237:1": ["magenta_glazed_terracotta", {"facing": "west"}],
1747 | "237:2": ["magenta_glazed_terracotta", {"facing": "north"}],
1748 | "237:3": ["magenta_glazed_terracotta", {"facing": "east"}],
1749 |
1750 | "238:0": ["light_blue_glazed_terracotta", {"facing": "south"}],
1751 | "238:1": ["light_blue_glazed_terracotta", {"facing": "west"}],
1752 | "238:2": ["light_blue_glazed_terracotta", {"facing": "north"}],
1753 | "238:3": ["light_blue_glazed_terracotta", {"facing": "east"}],
1754 |
1755 | "239:0": ["yellow_glazed_terracotta", {"facing": "south"}],
1756 | "239:1": ["yellow_glazed_terracotta", {"facing": "west"}],
1757 | "239:2": ["yellow_glazed_terracotta", {"facing": "north"}],
1758 | "239:3": ["yellow_glazed_terracotta", {"facing": "east"}],
1759 |
1760 | "240:0": ["lime_glazed_terracotta", {"facing": "south"}],
1761 | "240:1": ["lime_glazed_terracotta", {"facing": "west"}],
1762 | "240:2": ["lime_glazed_terracotta", {"facing": "north"}],
1763 | "240:3": ["lime_glazed_terracotta", {"facing": "east"}],
1764 |
1765 | "241:0": ["pink_glazed_terracotta", {"facing": "south"}],
1766 | "241:1": ["pink_glazed_terracotta", {"facing": "west"}],
1767 | "241:2": ["pink_glazed_terracotta", {"facing": "north"}],
1768 | "241:3": ["pink_glazed_terracotta", {"facing": "east"}],
1769 |
1770 | "242:0": ["gray_glazed_terracotta", {"facing": "south"}],
1771 | "242:1": ["gray_glazed_terracotta", {"facing": "west"}],
1772 | "242:2": ["gray_glazed_terracotta", {"facing": "north"}],
1773 | "242:3": ["gray_glazed_terracotta", {"facing": "east"}],
1774 |
1775 | "243:0": ["light_gray_glazed_terracotta", {"facing": "south"}],
1776 | "243:1": ["light_gray_glazed_terracotta", {"facing": "west"}],
1777 | "243:2": ["light_gray_glazed_terracotta", {"facing": "north"}],
1778 | "243:3": ["light_gray_glazed_terracotta", {"facing": "east"}],
1779 |
1780 | "244:0": ["cyan_glazed_terracotta", {"facing": "south"}],
1781 | "244:1": ["cyan_glazed_terracotta", {"facing": "west"}],
1782 | "244:2": ["cyan_glazed_terracotta", {"facing": "north"}],
1783 | "244:3": ["cyan_glazed_terracotta", {"facing": "east"}],
1784 |
1785 | "245:0": ["purple_glazed_terracotta", {"facing": "south"}],
1786 | "245:1": ["purple_glazed_terracotta", {"facing": "west"}],
1787 | "245:2": ["purple_glazed_terracotta", {"facing": "north"}],
1788 | "245:3": ["purple_glazed_terracotta", {"facing": "east"}],
1789 |
1790 | "246:0": ["blue_glazed_terracotta", {"facing": "south"}],
1791 | "246:1": ["blue_glazed_terracotta", {"facing": "west"}],
1792 | "246:2": ["blue_glazed_terracotta", {"facing": "north"}],
1793 | "246:3": ["blue_glazed_terracotta", {"facing": "east"}],
1794 |
1795 | "247:0": ["brown_glazed_terracotta", {"facing": "south"}],
1796 | "247:1": ["brown_glazed_terracotta", {"facing": "west"}],
1797 | "247:2": ["brown_glazed_terracotta", {"facing": "north"}],
1798 | "247:3": ["brown_glazed_terracotta", {"facing": "east"}],
1799 |
1800 | "248:0": ["green_glazed_terracotta", {"facing": "south"}],
1801 | "248:1": ["green_glazed_terracotta", {"facing": "west"}],
1802 | "248:2": ["green_glazed_terracotta", {"facing": "north"}],
1803 | "248:3": ["green_glazed_terracotta", {"facing": "east"}],
1804 |
1805 | "249:0": ["red_glazed_terracotta", {"facing": "south"}],
1806 | "249:1": ["red_glazed_terracotta", {"facing": "west"}],
1807 | "249:2": ["red_glazed_terracotta", {"facing": "north"}],
1808 | "249:3": ["red_glazed_terracotta", {"facing": "east"}],
1809 |
1810 | "250:0": ["black_glazed_terracotta", {"facing": "south"}],
1811 | "250:1": ["black_glazed_terracotta", {"facing": "west"}],
1812 | "250:2": ["black_glazed_terracotta", {"facing": "north"}],
1813 | "250:3": ["black_glazed_terracotta", {"facing": "east"}],
1814 |
1815 | "251:0": ["white_concrete", null],
1816 | "251:1": ["orange_concrete", null],
1817 | "251:2": ["magenta_concrete", null],
1818 | "251:3": ["light_blue_concrete", null],
1819 | "251:4": ["yellow_concrete", null],
1820 | "251:5": ["lime_concrete", null],
1821 | "251:6": ["pink_concrete", null],
1822 | "251:7": ["gray_concrete", null],
1823 | "251:8": ["light_gray_concrete", null],
1824 | "251:9": ["cyan_concrete", null],
1825 | "251:10": ["purple_concrete", null],
1826 | "251:11": ["blue_concrete", null],
1827 | "251:12": ["brown_concrete", null],
1828 | "251:13": ["green_concrete", null],
1829 | "251:14": ["red_concrete", null],
1830 | "251:15": ["black_concrete", null],
1831 | "252:0": ["white_concrete_powder", null],
1832 | "252:1": ["orange_concrete_powder", null],
1833 | "252:2": ["magenta_concrete_powder", null],
1834 | "252:3": ["light_blue_concrete_powder", null],
1835 | "252:4": ["yellow_concrete_powder", null],
1836 | "252:5": ["lime_concrete_powder", null],
1837 | "252:6": ["pink_concrete_powder", null],
1838 | "252:7": ["gray_concrete_powder", null],
1839 | "252:8": ["light_gray_concrete_powder", null],
1840 | "252:9": ["cyan_concrete_powder", null],
1841 | "252:10": ["purple_concrete_powder", null],
1842 | "252:11": ["blue_concrete_powder", null],
1843 | "252:12": ["brown_concrete_powder", null],
1844 | "252:13": ["green_concrete_powder", null],
1845 | "252:14": ["red_concrete_powder", null],
1846 | "252:15": ["black_concrete_powder", null],
1847 |
1848 | "255:0": ["structure_block", {"mode": "save"}],
1849 | "255:1": ["structure_block", {"mode": "load"}],
1850 | "255:2": ["structure_block", {"mode": "data"}],
1851 | "255:3": ["structure_block", {"mode": "corner"}]
1852 | }
1853 |
--------------------------------------------------------------------------------