amulet-core 1.9.18__tar.gz → 1.9.20__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of amulet-core might be problematic. Click here for more details.
- {amulet-core-1.9.18 → amulet-core-1.9.20}/PKG-INFO +13 -2
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/_version.py +3 -3
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/base_level/base_level.py +19 -10
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/anvil_world/_sector_manager.py +5 -98
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/anvil_world/format.py +98 -83
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/dimension.py +31 -65
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/format.py +62 -44
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_3463.py +1 -1
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet_core.egg-info/PKG-INFO +13 -2
- {amulet-core-1.9.18 → amulet-core-1.9.20}/setup.cfg +1 -1
- {amulet-core-1.9.18 → amulet-core-1.9.20}/MANIFEST.in +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/README.md +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/__pyinstaller/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/__pyinstaller/hook-amulet.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/abstract_base_entity.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/block.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/block_entity.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/cache.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/chunk/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/chunk/biomes.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/chunk/block_entity_dict.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/chunk/blocks.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/chunk/chunk.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/chunk/entity_list.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/chunk/status.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/data_types/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/data_types/generic_types.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/data_types/operation_types.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/data_types/world_types.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/data_types/wrapper_types.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/entity.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/errors.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/base/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/base/base_history.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/base/history_manager.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/base/revision_manager.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/changeable.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/data_types.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/history_manager/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/history_manager/container.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/history_manager/database.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/history_manager/meta.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/history_manager/object.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/revision_manager/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/revision_manager/disk.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/history/revision_manager/ram.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/item.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/base_level/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/base_level/chunk_manager.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/base_level/clone.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/base_level/player_manager.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/immutable_structure/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/immutable_structure/immutable_structure.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/immutable_structure/void_format_wrapper.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/structure.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/level/world.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/partial_3d_array/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/partial_3d_array/base_partial_3d_array.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/partial_3d_array/bounded_partial_3d_array.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/partial_3d_array/data_types.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/partial_3d_array/unbounded_partial_3d_array.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/partial_3d_array/util.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/player.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/registry/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/registry/base_registry.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/registry/biome_manager.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/registry/block_manager.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/selection/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/selection/abstract_selection.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/selection/box.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/selection/group.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/structure.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/wrapper/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/wrapper/chunk/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/wrapper/chunk/interface.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/wrapper/chunk/translator.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/wrapper/format_wrapper.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/wrapper/structure_format_wrapper.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/api/wrapper/world_format_wrapper.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/img/missing_world_icon.png +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/anvil_forge_world.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/anvil_world/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/anvil_world/data_pack/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/anvil_world/data_pack/data_pack.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/anvil_world/data_pack/data_pack_manager.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/anvil_world/dimension.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/anvil_world/region.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/construction/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/construction/format_wrapper.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/construction/interface.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/construction/section.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/construction/util.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/chunk.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/base_leveldb_interface.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/generate_interface.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_0.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_1.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_10.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_11.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_12.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_13.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_14.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_15.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_16.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_17.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_18.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_19.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_2.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_20.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_21.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_22.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_23.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_24.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_25.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_26.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_27.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_28.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_29.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_3.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_30.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_31.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_32.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_33.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_34.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_35.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_36.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_37.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_38.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_39.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_4.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_40.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_5.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_6.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_7.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_8.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_9.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/leveldb_world/interface/chunk/leveldb_chunk_versions.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/mcstructure/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/mcstructure/chunk.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/mcstructure/format_wrapper.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/mcstructure/interface.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/schematic/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/schematic/chunk.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/schematic/data_types.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/schematic/format_wrapper.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/schematic/interface.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/sponge_schem/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/sponge_schem/chunk.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/sponge_schem/format_wrapper.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/sponge_schem/interface.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/sponge_schem/varint/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/sponge_schem/varint/varint.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_0.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_1444.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_1466.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_1467.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_1484.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_1503.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_1519.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_1901.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_1908.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_1912.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_1934.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_2203.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_2529.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_2681.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_2709.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_2844.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/anvil_na.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/interfaces/chunk/anvil/base_anvil_interface.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/load.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/loader.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/translators/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/translators/chunk/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/translators/chunk/bedrock/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/translators/chunk/bedrock/bedrock_nbt_blockstate_translator.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/translators/chunk/bedrock/bedrock_numerical_translator.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/translators/chunk/bedrock/bedrock_psudo_numerical_translator.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/translators/chunk/java/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/translators/chunk/java/java_1_18_translator.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/translators/chunk/java/java_blockstate_translator.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/translators/chunk/java/java_numerical_translator.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/libs/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/libs/leveldb/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/operations/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/operations/clone.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/operations/delete_chunk.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/operations/fill.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/operations/paste.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/operations/replace.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/utils/__init__.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/utils/format_utils.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/utils/generator.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/utils/matrix.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/utils/numpy_helpers.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/utils/world_utils.py +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet_core.egg-info/SOURCES.txt +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet_core.egg-info/dependency_links.txt +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet_core.egg-info/entry_points.txt +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet_core.egg-info/requires.txt +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/amulet_core.egg-info/top_level.txt +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/pyproject.toml +0 -0
- {amulet-core-1.9.18 → amulet-core-1.9.20}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: amulet-core
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.20
|
|
4
4
|
Summary: A Python library for reading/writing Minecraft's various save formats.
|
|
5
5
|
Home-page: https://www.amuletmc.com
|
|
6
6
|
Author: James Clare, Ben Gothard et al.
|
|
@@ -8,10 +8,21 @@ Author-email: amuleteditor@gmail.com
|
|
|
8
8
|
Platform: any
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
10
|
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
12
|
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: numpy~=1.17
|
|
14
|
+
Requires-Dist: amulet-nbt~=2.0
|
|
15
|
+
Requires-Dist: pymctranslate~=1.2
|
|
16
|
+
Requires-Dist: portalocker~=2.4
|
|
17
|
+
Requires-Dist: amulet-leveldb~=1.0b0
|
|
18
|
+
Requires-Dist: platformdirs~=3.1
|
|
13
19
|
Provides-Extra: docs
|
|
20
|
+
Requires-Dist: Sphinx>=1.7.4; extra == "docs"
|
|
21
|
+
Requires-Dist: sphinx-autodoc-typehints>=1.3.0; extra == "docs"
|
|
22
|
+
Requires-Dist: sphinx_rtd_theme>=0.3.1; extra == "docs"
|
|
14
23
|
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: black>=22.3; extra == "dev"
|
|
25
|
+
Requires-Dist: pre_commit>=1.11.1; extra == "dev"
|
|
15
26
|
|
|
16
27
|
# Amulet Core
|
|
17
28
|
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2023-
|
|
11
|
+
"date": "2023-09-29T11:29:40+0100",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "1.9.
|
|
14
|
+
"full-revisionid": "b673f749bf1c348e31bf0594e71ffa30f6ea8519",
|
|
15
|
+
"version": "1.9.20"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -770,11 +770,19 @@ class BaseLevel:
|
|
|
770
770
|
chunk = self.get_chunk(cx, cz, dimension)
|
|
771
771
|
offset_x, offset_z = x - 16 * cx, z - 16 * cz
|
|
772
772
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
).
|
|
776
|
-
|
|
773
|
+
translator = self.translation_manager.get_version(*version).block
|
|
774
|
+
|
|
775
|
+
src_blocks = chunk.get_block(offset_x, y, offset_z).block_tuple
|
|
776
|
+
src_block_entity = chunk.block_entities.get((x, y, z))
|
|
777
|
+
|
|
778
|
+
output, extra_output, _ = translator.from_universal(
|
|
779
|
+
src_blocks[0], src_block_entity
|
|
777
780
|
)
|
|
781
|
+
if isinstance(output, Block):
|
|
782
|
+
for src_block in src_blocks[1:]:
|
|
783
|
+
converted_sub_block = translator.from_universal(src_block)[0]
|
|
784
|
+
if isinstance(converted_sub_block, Block):
|
|
785
|
+
output += converted_sub_block
|
|
778
786
|
return output, extra_output
|
|
779
787
|
|
|
780
788
|
def set_version_block(
|
|
@@ -812,13 +820,14 @@ class BaseLevel:
|
|
|
812
820
|
chunk = self.create_chunk(cx, cz, dimension)
|
|
813
821
|
offset_x, offset_z = x - 16 * cx, z - 16 * cz
|
|
814
822
|
|
|
815
|
-
(
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
block, block_entity
|
|
823
|
+
translator = self.translation_manager.get_version(*version).block
|
|
824
|
+
src_blocks = block.block_tuple
|
|
825
|
+
|
|
826
|
+
universal_block, universal_block_entity, _ = translator.to_universal(
|
|
827
|
+
src_blocks[0], block_entity
|
|
821
828
|
)
|
|
829
|
+
for src_block in src_blocks[1:]:
|
|
830
|
+
universal_block += translator.to_universal(src_block)[0]
|
|
822
831
|
chunk.set_block(offset_x, y, offset_z, universal_block),
|
|
823
832
|
if isinstance(universal_block_entity, BlockEntity):
|
|
824
833
|
chunk.block_entities[(x, y, z)] = universal_block_entity
|
{amulet-core-1.9.18 → amulet-core-1.9.20}/amulet/level/formats/anvil_world/_sector_manager.py
RENAMED
|
@@ -141,9 +141,9 @@ class SectorManager:
|
|
|
141
141
|
|
|
142
142
|
@property
|
|
143
143
|
def sectors(self) -> List[Sector]:
|
|
144
|
-
"""A list of reserved sectors"""
|
|
144
|
+
"""A list of reserved sectors. Ordered by their start location."""
|
|
145
145
|
with self._lock:
|
|
146
|
-
return list(self._reserved)
|
|
146
|
+
return list(sorted(self._reserved, key=lambda i: i.start))
|
|
147
147
|
|
|
148
148
|
def reserve_space(self, length: int) -> Sector:
|
|
149
149
|
"""
|
|
@@ -170,6 +170,7 @@ class SectorManager:
|
|
|
170
170
|
self._free_start[start_index] = free_sector
|
|
171
171
|
else:
|
|
172
172
|
del self._free_start[start_index]
|
|
173
|
+
self._reserved.add(sector)
|
|
173
174
|
return sector
|
|
174
175
|
elif self._resizable:
|
|
175
176
|
sector = Sector(self._stop, self._stop + length)
|
|
@@ -261,6 +262,8 @@ class SectorManager:
|
|
|
261
262
|
:param sector: The sector to free
|
|
262
263
|
"""
|
|
263
264
|
with self._lock:
|
|
265
|
+
if sector not in self._reserved:
|
|
266
|
+
raise ValueError("Sector was not reserved")
|
|
264
267
|
# remove the sector from the reserved storage
|
|
265
268
|
self._reserved.remove(sector)
|
|
266
269
|
|
|
@@ -286,99 +289,3 @@ class SectorManager:
|
|
|
286
289
|
|
|
287
290
|
self._free_start.insert(index, sector)
|
|
288
291
|
self._add_size_sector(sector)
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
def validate(m):
|
|
292
|
-
assert set(m._free_start) == set(m._free_size)
|
|
293
|
-
free = sorted(list(m._free_start) + list(m._reserved), key=lambda k: k.start)
|
|
294
|
-
if free:
|
|
295
|
-
for i in range(len(free) - 1):
|
|
296
|
-
assert free[i].stop == free[i + 1].start
|
|
297
|
-
assert free[-1].stop == m._stop
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
def test1():
|
|
301
|
-
m = SectorManager(2, 3)
|
|
302
|
-
validate(m)
|
|
303
|
-
m.reserve(Sector(2, 3))
|
|
304
|
-
validate(m)
|
|
305
|
-
m.reserve(Sector(3, 4))
|
|
306
|
-
validate(m)
|
|
307
|
-
print(m.sectors)
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
def test2():
|
|
311
|
-
m = SectorManager(2, 102)
|
|
312
|
-
|
|
313
|
-
m.reserve(Sector(5, 6))
|
|
314
|
-
validate(m)
|
|
315
|
-
m.reserve(Sector(6, 7))
|
|
316
|
-
validate(m)
|
|
317
|
-
# m.reserve(Sector(7, 8))
|
|
318
|
-
m.reserve(Sector(8, 9))
|
|
319
|
-
validate(m)
|
|
320
|
-
|
|
321
|
-
try:
|
|
322
|
-
m.reserve(Sector(6, 8))
|
|
323
|
-
except NoValidSector:
|
|
324
|
-
pass
|
|
325
|
-
else:
|
|
326
|
-
raise Exception
|
|
327
|
-
|
|
328
|
-
validate(m)
|
|
329
|
-
|
|
330
|
-
try:
|
|
331
|
-
m.reserve(Sector(7, 9))
|
|
332
|
-
except NoValidSector:
|
|
333
|
-
pass
|
|
334
|
-
else:
|
|
335
|
-
raise Exception
|
|
336
|
-
|
|
337
|
-
validate(m)
|
|
338
|
-
m.free(Sector(5, 6))
|
|
339
|
-
validate(m)
|
|
340
|
-
m.free(Sector(6, 7))
|
|
341
|
-
validate(m)
|
|
342
|
-
m.free(Sector(8, 9))
|
|
343
|
-
validate(m)
|
|
344
|
-
|
|
345
|
-
m.reserve(Sector(6, 8))
|
|
346
|
-
validate(m)
|
|
347
|
-
m.free(Sector(6, 8))
|
|
348
|
-
validate(m)
|
|
349
|
-
|
|
350
|
-
m.reserve(Sector(7, 9))
|
|
351
|
-
validate(m)
|
|
352
|
-
m.free(Sector(7, 9))
|
|
353
|
-
|
|
354
|
-
validate(m)
|
|
355
|
-
|
|
356
|
-
assert len(m._free_start) == 1
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
# def test3():
|
|
360
|
-
# reserve a number of single length units
|
|
361
|
-
# for _ in range(20):
|
|
362
|
-
# i = free_indexes.pop(random.randrange(len(free_indexes)))
|
|
363
|
-
# m.reserve(Sector(i, i+1))
|
|
364
|
-
# validate(m)
|
|
365
|
-
# reserved_indexes.append(i)
|
|
366
|
-
#
|
|
367
|
-
# for _ in range(20):
|
|
368
|
-
# index = random.randrange(len(free_indexes))
|
|
369
|
-
# di = 1
|
|
370
|
-
# i = free_indexes.pop(index)
|
|
371
|
-
#
|
|
372
|
-
# for _ in range(10_000):
|
|
373
|
-
# m.reserve(Sector(i, i+1))
|
|
374
|
-
# validate(m)
|
|
375
|
-
# print(m.sectors)
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
def test():
|
|
379
|
-
test1()
|
|
380
|
-
test2()
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
if __name__ == "__main__":
|
|
384
|
-
test()
|
|
@@ -231,93 +231,108 @@ class AnvilFormat(WorldFormatWrapper[VersionNumberInt]):
|
|
|
231
231
|
layers=("region",) + ("entities",) * (self.version >= 2681),
|
|
232
232
|
)
|
|
233
233
|
self._dimension_name_map[dimension_name] = relative_dimension_path
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
234
|
+
self._bounds[dimension_name] = self._get_dimenion_bounds(dimension_name)
|
|
235
|
+
|
|
236
|
+
def _get_dimenion_bounds(self, dimension_type_str: Dimension) -> SelectionGroup:
|
|
237
|
+
if self.version >= 2709: # This number might be smaller
|
|
238
|
+
# If in a version that supports custom height data packs
|
|
239
|
+
dimension_settings = (
|
|
240
|
+
self.root_tag.compound.get_compound("Data", CompoundTag())
|
|
241
|
+
.get_compound("WorldGenSettings", CompoundTag())
|
|
242
|
+
.get_compound("dimensions", CompoundTag())
|
|
243
|
+
.get_compound(dimension_type_str, CompoundTag())
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
# "type" can be a reference (string) or inline (compound) dimension-type data.
|
|
247
|
+
dimension_type = dimension_settings.get("type")
|
|
248
|
+
|
|
249
|
+
if isinstance(dimension_type, StringTag):
|
|
250
|
+
# Reference type. Load the dimension data
|
|
251
|
+
dimension_type_str = dimension_type.py_str
|
|
252
|
+
if ":" in dimension_type_str:
|
|
253
|
+
namespace, base_name = dimension_type_str.split(":", 1)
|
|
254
|
+
else:
|
|
255
|
+
namespace = "minecraft"
|
|
256
|
+
base_name = dimension_type_str
|
|
257
|
+
name_tuple = namespace, base_name
|
|
258
|
+
|
|
259
|
+
# First try and load the reference from the data pack and then from defaults
|
|
260
|
+
dimension_path = f"data/{namespace}/dimension_type/{base_name}.json"
|
|
261
|
+
if self.data_pack.has_file(dimension_path):
|
|
262
|
+
with self.data_pack.open(dimension_path) as d:
|
|
263
|
+
try:
|
|
264
|
+
dimension_settings_json = json.load(d)
|
|
265
|
+
except json.JSONDecodeError:
|
|
266
|
+
pass
|
|
267
|
+
else:
|
|
268
|
+
if "min_y" in dimension_settings_json and isinstance(
|
|
269
|
+
dimension_settings_json["min_y"], int
|
|
270
|
+
):
|
|
271
|
+
min_y = dimension_settings_json["min_y"]
|
|
272
|
+
if min_y % 16:
|
|
273
|
+
min_y = 16 * (min_y // 16)
|
|
274
|
+
else:
|
|
275
|
+
min_y = 0
|
|
276
|
+
if "height" in dimension_settings_json and isinstance(
|
|
277
|
+
dimension_settings_json["height"], int
|
|
278
|
+
):
|
|
279
|
+
height = dimension_settings_json["height"]
|
|
280
|
+
if height % 16:
|
|
281
|
+
height = -16 * (-height // 16)
|
|
282
|
+
else:
|
|
283
|
+
height = 256
|
|
284
|
+
|
|
285
|
+
return SelectionGroup(
|
|
254
286
|
SelectionBox(
|
|
255
|
-
(-30_000_000,
|
|
256
|
-
(30_000_000,
|
|
287
|
+
(-30_000_000, min_y, -30_000_000),
|
|
288
|
+
(30_000_000, min_y + height, 30_000_000),
|
|
257
289
|
)
|
|
258
290
|
)
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
and isinstance(
|
|
272
|
-
dimension_settings_json["min_y"], int
|
|
273
|
-
)
|
|
274
|
-
):
|
|
275
|
-
min_y = dimension_settings_json["min_y"]
|
|
276
|
-
if min_y % 16:
|
|
277
|
-
min_y = 16 * (min_y // 16)
|
|
278
|
-
else:
|
|
279
|
-
min_y = 0
|
|
280
|
-
if (
|
|
281
|
-
"height" in dimension_settings_json
|
|
282
|
-
and isinstance(
|
|
283
|
-
dimension_settings_json["height"], int
|
|
284
|
-
)
|
|
285
|
-
):
|
|
286
|
-
height = dimension_settings_json["height"]
|
|
287
|
-
if height % 16:
|
|
288
|
-
height = -16 * (-height // 16)
|
|
289
|
-
else:
|
|
290
|
-
height = 256
|
|
291
|
-
|
|
292
|
-
bounds = SelectionGroup(
|
|
293
|
-
SelectionBox(
|
|
294
|
-
(-30_000_000, min_y, -30_000_000),
|
|
295
|
-
(30_000_000, min_y + height, 30_000_000),
|
|
296
|
-
)
|
|
297
|
-
)
|
|
298
|
-
|
|
299
|
-
elif isinstance(dimension_tag, CompoundTag):
|
|
300
|
-
# the settings are here
|
|
301
|
-
dimension_compound_tag = dimension_tag
|
|
302
|
-
min_y = (
|
|
303
|
-
dimension_compound_tag.get_int("min_y", IntTag()).py_int // 16
|
|
304
|
-
) * 16
|
|
305
|
-
height = (
|
|
306
|
-
-dimension_compound_tag.get_int("height", IntTag(256)).py_int
|
|
307
|
-
// 16
|
|
308
|
-
) * -16
|
|
309
|
-
bounds = SelectionGroup(
|
|
310
|
-
SelectionBox(
|
|
311
|
-
(-30_000_000, min_y, -30_000_000),
|
|
312
|
-
(30_000_000, min_y + height, 30_000_000),
|
|
291
|
+
|
|
292
|
+
elif name_tuple in {
|
|
293
|
+
("minecraft", "overworld"),
|
|
294
|
+
("minecraft", "overworld_caves"),
|
|
295
|
+
}:
|
|
296
|
+
if self.version >= 2825:
|
|
297
|
+
# If newer than the height change version
|
|
298
|
+
return SelectionGroup(
|
|
299
|
+
SelectionBox(
|
|
300
|
+
(-30_000_000, -64, -30_000_000),
|
|
301
|
+
(30_000_000, 320, 30_000_000),
|
|
302
|
+
)
|
|
313
303
|
)
|
|
314
|
-
|
|
304
|
+
else:
|
|
305
|
+
return DefaultSelection
|
|
306
|
+
elif name_tuple in {
|
|
307
|
+
("minecraft", "the_nether"),
|
|
308
|
+
("minecraft", "the_end"),
|
|
309
|
+
}:
|
|
310
|
+
return DefaultSelection
|
|
315
311
|
else:
|
|
316
|
-
log.error(
|
|
317
|
-
|
|
312
|
+
log.error(f"Could not find dimension_type {':'.join(name_tuple)}")
|
|
313
|
+
|
|
314
|
+
elif isinstance(dimension_type, CompoundTag):
|
|
315
|
+
# Inline type
|
|
316
|
+
dimension_type_compound = dimension_type
|
|
317
|
+
min_y = (
|
|
318
|
+
dimension_type_compound.get_int("min_y", IntTag()).py_int // 16
|
|
319
|
+
) * 16
|
|
320
|
+
height = (
|
|
321
|
+
-dimension_type_compound.get_int("height", IntTag(256)).py_int // 16
|
|
322
|
+
) * -16
|
|
323
|
+
return SelectionGroup(
|
|
324
|
+
SelectionBox(
|
|
325
|
+
(-30_000_000, min_y, -30_000_000),
|
|
326
|
+
(30_000_000, min_y + height, 30_000_000),
|
|
318
327
|
)
|
|
328
|
+
)
|
|
329
|
+
else:
|
|
330
|
+
log.error(
|
|
331
|
+
f'level_dat["Data"]["WorldGenSettings"]["dimensions"]["{dimension_type_str}"]["type"] was not a StringTag or CompoundTag.'
|
|
332
|
+
)
|
|
319
333
|
|
|
320
|
-
|
|
334
|
+
# Return the default if nothing else returned
|
|
335
|
+
return DefaultSelection
|
|
321
336
|
|
|
322
337
|
def _get_interface(self, raw_chunk_data: Optional[Any] = None) -> "Interface":
|
|
323
338
|
from amulet.level.loader import Interfaces
|
|
@@ -405,9 +420,9 @@ class AnvilFormat(WorldFormatWrapper[VersionNumberInt]):
|
|
|
405
420
|
self._register_dimension("DIM-1", THE_NETHER)
|
|
406
421
|
self._register_dimension("DIM1", THE_END)
|
|
407
422
|
|
|
408
|
-
for
|
|
409
|
-
|
|
410
|
-
|
|
423
|
+
for level_path in glob.glob(os.path.join(glob.escape(self.path), "DIM*")):
|
|
424
|
+
if os.path.isdir(level_path):
|
|
425
|
+
dir_name = os.path.basename(level_path)
|
|
411
426
|
if AnvilDimensionManager.level_regex.fullmatch(dir_name) is None:
|
|
412
427
|
continue
|
|
413
428
|
self._register_dimension(dir_name)
|
|
@@ -8,7 +8,6 @@ from typing import (
|
|
|
8
8
|
List,
|
|
9
9
|
TYPE_CHECKING,
|
|
10
10
|
Tuple,
|
|
11
|
-
Union,
|
|
12
11
|
)
|
|
13
12
|
from threading import RLock
|
|
14
13
|
import logging
|
|
@@ -25,21 +24,17 @@ from amulet_nbt import (
|
|
|
25
24
|
utf8_escape_encoder,
|
|
26
25
|
)
|
|
27
26
|
|
|
28
|
-
from amulet.api.errors import ChunkDoesNotExist
|
|
27
|
+
from amulet.api.errors import ChunkDoesNotExist
|
|
29
28
|
from amulet.api.data_types import ChunkCoordinates
|
|
30
29
|
from leveldb import LevelDB
|
|
31
30
|
from .chunk import ChunkData
|
|
32
31
|
|
|
33
32
|
if TYPE_CHECKING:
|
|
34
|
-
from amulet.api.data_types import Dimension
|
|
35
33
|
from .format import LevelDBFormat
|
|
36
34
|
|
|
37
35
|
log = logging.getLogger(__name__)
|
|
38
36
|
|
|
39
37
|
InternalDimension = Optional[int]
|
|
40
|
-
OVERWORLD = "minecraft:overworld"
|
|
41
|
-
THE_NETHER = "minecraft:the_nether"
|
|
42
|
-
THE_END = "minecraft:the_end"
|
|
43
38
|
|
|
44
39
|
|
|
45
40
|
class ActorCounter:
|
|
@@ -102,12 +97,11 @@ class LevelDBDimensionManager:
|
|
|
102
97
|
self._actor_counter = ActorCounter.from_level(level)
|
|
103
98
|
# self._levels format Dict[level, Dict[Tuple[cx, cz], List[Tuple[full_key, key_extension]]]]
|
|
104
99
|
self._levels: Dict[InternalDimension, Set[ChunkCoordinates]] = {}
|
|
105
|
-
self._dimension_name_map: Dict["Dimension", InternalDimension] = {}
|
|
106
100
|
self._lock = RLock()
|
|
107
101
|
|
|
108
|
-
self.register_dimension(None
|
|
109
|
-
self.register_dimension(1
|
|
110
|
-
self.register_dimension(2
|
|
102
|
+
self.register_dimension(None) # overworld
|
|
103
|
+
self.register_dimension(1) # the nether
|
|
104
|
+
self.register_dimension(2) # the end
|
|
111
105
|
|
|
112
106
|
for key in self._db.keys():
|
|
113
107
|
if 9 <= len(key) <= 10 and key[8] in [44, 118]: # "," "v"
|
|
@@ -117,63 +111,36 @@ class LevelDBDimensionManager:
|
|
|
117
111
|
self._add_chunk(key, has_level=True)
|
|
118
112
|
|
|
119
113
|
@property
|
|
120
|
-
def dimensions(self) -> List[
|
|
114
|
+
def dimensions(self) -> List[InternalDimension]:
|
|
121
115
|
"""A list of all the levels contained in the world"""
|
|
122
|
-
return list(self.
|
|
116
|
+
return list(self._levels)
|
|
123
117
|
|
|
124
|
-
def register_dimension(
|
|
125
|
-
self,
|
|
126
|
-
dimension_internal: InternalDimension,
|
|
127
|
-
dimension_name: Optional["Dimension"] = None,
|
|
128
|
-
):
|
|
118
|
+
def register_dimension(self, dimension: InternalDimension):
|
|
129
119
|
"""
|
|
130
120
|
Register a new dimension.
|
|
131
121
|
|
|
132
|
-
:param
|
|
133
|
-
:param dimension_name: The name of the dimension shown to the user
|
|
122
|
+
:param dimension: The internal representation of the dimension
|
|
134
123
|
:return:
|
|
135
124
|
"""
|
|
136
|
-
if dimension_name is None:
|
|
137
|
-
dimension_name: "Dimension" = f"DIM{dimension_internal}"
|
|
138
|
-
|
|
139
125
|
with self._lock:
|
|
140
|
-
if
|
|
141
|
-
|
|
142
|
-
and dimension_name not in self._dimension_name_map
|
|
143
|
-
):
|
|
144
|
-
self._levels[dimension_internal] = set()
|
|
145
|
-
self._dimension_name_map[dimension_name] = dimension_internal
|
|
146
|
-
|
|
147
|
-
def _get_internal_dimension(self, dimension: "Dimension") -> InternalDimension:
|
|
148
|
-
if dimension in self._dimension_name_map:
|
|
149
|
-
return self._dimension_name_map[dimension]
|
|
150
|
-
else:
|
|
151
|
-
raise DimensionDoesNotExist(dimension)
|
|
126
|
+
if dimension not in self._levels:
|
|
127
|
+
self._levels[dimension] = set()
|
|
152
128
|
|
|
153
|
-
def all_chunk_coords(self, dimension:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
return self._levels[internal_dimension]
|
|
129
|
+
def all_chunk_coords(self, dimension: InternalDimension) -> Set[ChunkCoordinates]:
|
|
130
|
+
if dimension in self._levels:
|
|
131
|
+
return self._levels[dimension]
|
|
157
132
|
else:
|
|
158
133
|
return set()
|
|
159
134
|
|
|
160
135
|
@staticmethod
|
|
161
|
-
def _get_key(cx: int, cz: int,
|
|
162
|
-
if
|
|
136
|
+
def _get_key(cx: int, cz: int, dimension: InternalDimension) -> bytes:
|
|
137
|
+
if dimension is None:
|
|
163
138
|
return struct.pack("<ii", cx, cz)
|
|
164
139
|
else:
|
|
165
|
-
return struct.pack("<iii", cx, cz,
|
|
166
|
-
|
|
167
|
-
def _has_chunk(
|
|
168
|
-
self, cx: int, cz: int, internal_dimension: InternalDimension
|
|
169
|
-
) -> bool:
|
|
170
|
-
return (
|
|
171
|
-
internal_dimension in self._levels
|
|
172
|
-
and (cx, cz) in self._levels[internal_dimension]
|
|
173
|
-
)
|
|
140
|
+
return struct.pack("<iii", cx, cz, dimension)
|
|
174
141
|
|
|
175
|
-
def has_chunk(self, cx: int, cz: int, dimension:
|
|
176
|
-
return self.
|
|
142
|
+
def has_chunk(self, cx: int, cz: int, dimension: InternalDimension) -> bool:
|
|
143
|
+
return dimension in self._levels and (cx, cz) in self._levels[dimension]
|
|
177
144
|
|
|
178
145
|
def _add_chunk(self, key_: bytes, has_level: bool = False):
|
|
179
146
|
if has_level:
|
|
@@ -185,14 +152,15 @@ class LevelDBDimensionManager:
|
|
|
185
152
|
self.register_dimension(level)
|
|
186
153
|
self._levels[level].add((cx, cz))
|
|
187
154
|
|
|
188
|
-
def get_chunk_data(
|
|
155
|
+
def get_chunk_data(
|
|
156
|
+
self, cx: int, cz: int, dimension: InternalDimension
|
|
157
|
+
) -> ChunkData:
|
|
189
158
|
"""Get a dictionary of chunk key extension in bytes to the raw data in the key.
|
|
190
159
|
chunk key extension are the character(s) after <cx><cz>[level] in the key
|
|
191
160
|
Will raise ChunkDoesNotExist if the chunk does not exist
|
|
192
161
|
"""
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
prefix = self._get_key(cx, cz, internal_dimension)
|
|
162
|
+
if self.has_chunk(cx, cz, dimension):
|
|
163
|
+
prefix = self._get_key(cx, cz, dimension)
|
|
196
164
|
prefix_len = len(prefix)
|
|
197
165
|
iter_end = prefix + b"\xff\xff\xff\xff"
|
|
198
166
|
|
|
@@ -288,13 +256,12 @@ class LevelDBDimensionManager:
|
|
|
288
256
|
cx: int,
|
|
289
257
|
cz: int,
|
|
290
258
|
chunk_data: ChunkData,
|
|
291
|
-
dimension:
|
|
259
|
+
dimension: InternalDimension,
|
|
292
260
|
):
|
|
293
261
|
"""pass data to the region file class"""
|
|
294
262
|
# get the region key
|
|
295
|
-
|
|
296
|
-
self.
|
|
297
|
-
key_prefix = self._get_key(cx, cz, internal_dimension)
|
|
263
|
+
self._levels[dimension].add((cx, cz))
|
|
264
|
+
key_prefix = self._get_key(cx, cz, dimension)
|
|
298
265
|
|
|
299
266
|
batch = {}
|
|
300
267
|
|
|
@@ -388,15 +355,14 @@ class LevelDBDimensionManager:
|
|
|
388
355
|
if batch:
|
|
389
356
|
self._db.putBatch(batch)
|
|
390
357
|
|
|
391
|
-
def delete_chunk(self, cx: int, cz: int, dimension:
|
|
392
|
-
if dimension not in self.
|
|
358
|
+
def delete_chunk(self, cx: int, cz: int, dimension: InternalDimension):
|
|
359
|
+
if dimension not in self._levels:
|
|
393
360
|
return # dimension does not exists so chunk cannot
|
|
394
361
|
|
|
395
|
-
|
|
396
|
-
if not self._has_chunk(cx, cz, internal_dimension):
|
|
362
|
+
if not self.has_chunk(cx, cz, dimension):
|
|
397
363
|
return # chunk does not exists
|
|
398
364
|
|
|
399
|
-
prefix = self._get_key(cx, cz,
|
|
365
|
+
prefix = self._get_key(cx, cz, dimension)
|
|
400
366
|
prefix_len = len(prefix)
|
|
401
367
|
iter_end = prefix + b"\xff\xff\xff\xff"
|
|
402
368
|
keys = []
|
|
@@ -414,6 +380,6 @@ class LevelDBDimensionManager:
|
|
|
414
380
|
actor_key = b"actorprefix" + digp[i : i + 8]
|
|
415
381
|
self._db.delete(actor_key)
|
|
416
382
|
|
|
417
|
-
self._levels[
|
|
383
|
+
self._levels[dimension].remove((cx, cz))
|
|
418
384
|
for key in keys:
|
|
419
385
|
self._db.delete(key)
|