amulet-core 2.0a6__cp312-cp312-win_amd64.whl → 2.0a8__cp312-cp312-win_amd64.whl
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/__init__.cp312-win_amd64.pyd +0 -0
- amulet/__init__.py.cpp +6 -0
- amulet/__init__.pyi +2 -2
- amulet/_init.py +0 -2
- amulet/_version.py +3 -3
- amulet/biome.pyi +0 -2
- amulet/block.pyi +0 -2
- amulet/block_entity.pyi +0 -2
- amulet/chunk.hpp +2 -1
- amulet/chunk.pyi +0 -2
- amulet/chunk_components.pyi +20 -18
- amulet/collections/eq.py.hpp +1 -1
- amulet/collections/mapping.py.hpp +18 -11
- amulet/collections/mutable_mapping.py.hpp +17 -6
- amulet/collections/sequence.py.hpp +5 -6
- amulet/collections.pyi +8 -5
- amulet/entity.py +22 -20
- amulet/game/translate/_functions/_code_functions/_text.py +2 -2
- amulet/game/translate/_functions/abc.py +10 -3
- amulet/img/__init__.py +10 -0
- amulet/img/missing_no.png +0 -0
- amulet/img/missing_pack.png +0 -0
- amulet/level/__init__.pyi +2 -6
- amulet/level/abc/_chunk_handle.py +45 -22
- amulet/level/abc/_level/_creatable_level.py +1 -2
- amulet/level/abc/_level/_level.py +1 -5
- amulet/level/java/__init__.pyi +0 -5
- amulet/level/java/_raw/__init__.pyi +0 -4
- amulet/level/java/_raw/java_chunk_decode.cpp +2 -4
- amulet/level/java/long_array.pyi +2 -1
- amulet/mesh/block/__init__.pyi +301 -0
- amulet/mesh/block/_cube.py +198 -0
- amulet/mesh/block/_missing_block.py +20 -0
- amulet/mesh/block/block_mesh.cpp +107 -0
- amulet/mesh/block/block_mesh.hpp +207 -0
- amulet/mesh/util.py +17 -0
- amulet/player.py +4 -6
- amulet/pybind11/collections.hpp +80 -38
- amulet/pybind11/numpy.hpp +26 -0
- amulet/pybind11/py_module.hpp +16 -51
- amulet/pybind11/type_hints.hpp +51 -0
- amulet/pybind11/types.hpp +14 -6
- amulet/pybind11/typing.hpp +7 -0
- amulet/resource_pack/__init__.py +63 -0
- amulet/resource_pack/abc/__init__.py +2 -0
- amulet/resource_pack/abc/resource_pack.py +38 -0
- amulet/resource_pack/abc/resource_pack_manager.py +85 -0
- amulet/resource_pack/java/__init__.py +2 -0
- amulet/resource_pack/java/download_resources.py +212 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_black.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_brown.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_cyan.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_green.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_lime.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_magenta.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_orange.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_pink.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_purple.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_red.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_white.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_yellow.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/barrier.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/end_portal.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/grass.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/structure_void.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/pack.png +0 -0
- amulet/resource_pack/java/resource_pack.py +44 -0
- amulet/resource_pack/java/resource_pack_manager.py +563 -0
- amulet/resource_pack/unknown_resource_pack.py +10 -0
- amulet/utils/__init__.pyi +0 -5
- amulet/utils/call_spec/_call_spec.py +2 -7
- amulet/utils/cast.py +10 -0
- amulet/utils/comment_json.py +188 -0
- amulet/utils/matrix.py +3 -3
- amulet/utils/numpy_helpers.py +2 -2
- amulet/utils/shareable_lock.py +2 -2
- amulet/utils/world_utils.py +2 -2
- amulet/version.pyi +0 -8
- {amulet_core-2.0a6.dist-info → amulet_core-2.0a8.dist-info}/METADATA +2 -2
- {amulet_core-2.0a6.dist-info → amulet_core-2.0a8.dist-info}/RECORD +91 -103
- {amulet_core-2.0a6.dist-info → amulet_core-2.0a8.dist-info}/WHEEL +1 -1
- amulet/chunk_/components/biome.py +0 -155
- amulet/chunk_/components/block_entity.py +0 -117
- amulet/chunk_/components/entity.py +0 -64
- amulet/chunk_/components/height_2d.py +0 -16
- amulet/level/bedrock/__init__.py +0 -2
- amulet/level/bedrock/_chunk_handle.py +0 -19
- amulet/level/bedrock/_dimension.py +0 -22
- amulet/level/bedrock/_level.py +0 -187
- amulet/level/bedrock/_raw/__init__.py +0 -5
- amulet/level/bedrock/_raw/_actor_counter.py +0 -53
- amulet/level/bedrock/_raw/_chunk.py +0 -54
- amulet/level/bedrock/_raw/_chunk_decode.py +0 -668
- amulet/level/bedrock/_raw/_chunk_encode.py +0 -602
- amulet/level/bedrock/_raw/_constant.py +0 -9
- amulet/level/bedrock/_raw/_dimension.py +0 -343
- amulet/level/bedrock/_raw/_level.py +0 -463
- amulet/level/bedrock/_raw/_level_dat.py +0 -90
- amulet/level/bedrock/_raw/_typing.py +0 -6
- amulet/level/bedrock/_raw/leveldb_chunk_versions.py +0 -83
- amulet/level/bedrock/chunk/__init__.py +0 -1
- amulet/level/bedrock/chunk/_chunk.py +0 -126
- amulet/level/bedrock/chunk/components/chunk_version.py +0 -12
- amulet/level/bedrock/chunk/components/finalised_state.py +0 -13
- amulet/level/bedrock/chunk/components/raw_chunk.py +0 -15
- amulet/level/construction/__init__.py +0 -0
- amulet/level/java/_chunk_handle.pyi +0 -15
- amulet/level/java/_dimension.pyi +0 -13
- amulet/level/java/_level.pyi +0 -120
- amulet/level/java/_raw/_chunk_decode.py +0 -561
- amulet/level/java/_raw/_chunk_encode.py +0 -463
- amulet/level/java/_raw/_constant.pyi +0 -20
- amulet/level/java/_raw/_data_pack/__init__.pyi +0 -8
- amulet/level/java/_raw/_data_pack/data_pack.pyi +0 -197
- amulet/level/java/_raw/_data_pack/data_pack_manager.pyi +0 -75
- amulet/level/java/_raw/_dimension.pyi +0 -72
- amulet/level/java/_raw/_level.pyi +0 -238
- amulet/level/java/_raw/_typing.pyi +0 -5
- amulet/level/java/anvil/__init__.pyi +0 -11
- amulet/level/java/anvil/_dimension.pyi +0 -109
- amulet/level/java/anvil/_region.pyi +0 -197
- amulet/level/java/anvil/_sector_manager.pyi +0 -142
- amulet/level/java_forge/__init__.py +0 -0
- amulet/level/mcstructure/__init__.py +0 -0
- amulet/level/nbt/__init__.py +0 -0
- amulet/level/schematic/__init__.py +0 -0
- amulet/level/sponge_schematic/__init__.py +0 -0
- amulet/pybind11/python.hpp +0 -14
- amulet/utils/call_spec/__init__.pyi +0 -53
- amulet/utils/call_spec/_call_spec.pyi +0 -272
- amulet/utils/matrix.pyi +0 -177
- amulet/utils/shareable_lock.pyi +0 -190
- amulet/utils/signal/__init__.pyi +0 -25
- amulet/utils/signal/_signal.pyi +0 -84
- amulet/utils/task_manager.pyi +0 -168
- amulet/utils/typing.py +0 -4
- amulet/utils/typing.pyi +0 -6
- amulet/utils/weakref.pyi +0 -50
- amulet/utils/world_utils.pyi +0 -109
- /amulet/img/{missing_world_icon.png → missing_world.png} +0 -0
- /amulet/{level/bedrock/chunk/components → mesh}/__init__.py +0 -0
- {amulet_core-2.0a6.dist-info → amulet_core-2.0a8.dist-info}/entry_points.txt +0 -0
- {amulet_core-2.0a6.dist-info → amulet_core-2.0a8.dist-info}/top_level.txt +0 -0
|
@@ -1,463 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
from typing import TYPE_CHECKING, Callable
|
|
3
|
-
from functools import cache
|
|
4
|
-
import logging
|
|
5
|
-
|
|
6
|
-
import numpy
|
|
7
|
-
from amulet_nbt import (
|
|
8
|
-
NamedTag,
|
|
9
|
-
AbstractBaseIntTag,
|
|
10
|
-
ByteTag,
|
|
11
|
-
ShortTag,
|
|
12
|
-
IntTag,
|
|
13
|
-
LongTag,
|
|
14
|
-
FloatTag,
|
|
15
|
-
DoubleTag,
|
|
16
|
-
StringTag,
|
|
17
|
-
CompoundTag,
|
|
18
|
-
ListTag,
|
|
19
|
-
ByteArrayTag,
|
|
20
|
-
IntArrayTag,
|
|
21
|
-
LongArrayTag,
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
from amulet.game import get_game_version
|
|
25
|
-
from amulet.game.java import JavaGameVersion, Waterloggable
|
|
26
|
-
from amulet.utils.world_utils import encode_long_array, to_nibble_array
|
|
27
|
-
from amulet.utils.numpy import unique_inverse
|
|
28
|
-
|
|
29
|
-
from amulet.block import Block, BlockStack
|
|
30
|
-
from amulet.biome import Biome
|
|
31
|
-
from amulet.block_entity import BlockEntity
|
|
32
|
-
from amulet.entity import Entity
|
|
33
|
-
from amulet.version import VersionNumber, VersionRange
|
|
34
|
-
from amulet.palette import BlockPalette
|
|
35
|
-
|
|
36
|
-
from amulet.chunk.components.height_2d import Height2DComponent
|
|
37
|
-
from amulet.chunk.components.biome import (
|
|
38
|
-
Biome2DComponent,
|
|
39
|
-
Biome2DComponentData,
|
|
40
|
-
Biome3DComponent,
|
|
41
|
-
Biome3DComponentData,
|
|
42
|
-
)
|
|
43
|
-
from amulet.chunk.components.block import BlockComponent, BlockComponentData
|
|
44
|
-
from amulet.chunk.components.sub_chunk_array import SubChunkArrayContainer
|
|
45
|
-
from amulet.chunk.components.block_entity import (
|
|
46
|
-
BlockEntityComponent,
|
|
47
|
-
BlockEntityComponentData,
|
|
48
|
-
)
|
|
49
|
-
from amulet.chunk.components.entity import EntityComponent, EntityComponentData
|
|
50
|
-
|
|
51
|
-
from amulet.level.java.anvil import RawChunkType
|
|
52
|
-
from amulet.level.java.chunk import JavaChunk
|
|
53
|
-
|
|
54
|
-
from amulet.level.java.chunk.components.raw_chunk import RawChunkComponent
|
|
55
|
-
from amulet.level.java.chunk.components.data_version import DataVersionComponent
|
|
56
|
-
from amulet.level.java.chunk.components.legacy_version import LegacyVersionComponent
|
|
57
|
-
from amulet.level.java.chunk.components.status import StatusComponent
|
|
58
|
-
from amulet.level.java.chunk.components.light_populated import LightPopulatedComponent
|
|
59
|
-
from amulet.level.java.chunk.components.terrain_populated import (
|
|
60
|
-
TerrainPopulatedComponent,
|
|
61
|
-
)
|
|
62
|
-
from amulet.level.java.chunk.components.named_height_2d import (
|
|
63
|
-
NamedHeight2DComponent,
|
|
64
|
-
NamedHeight2DData,
|
|
65
|
-
)
|
|
66
|
-
from amulet.level.java.chunk.components.last_update import LastUpdateComponent
|
|
67
|
-
from amulet.level.java.chunk.components.inhabited_time import InhabitedTimeComponent
|
|
68
|
-
|
|
69
|
-
if TYPE_CHECKING:
|
|
70
|
-
from ._level import JavaRawLevel
|
|
71
|
-
from ._dimension import JavaRawDimension
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
log = logging.getLogger(__name__)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def native_to_raw(
|
|
78
|
-
raw_level: JavaRawLevel,
|
|
79
|
-
dimension: JavaRawDimension,
|
|
80
|
-
chunk: JavaChunk,
|
|
81
|
-
cx: int,
|
|
82
|
-
cz: int,
|
|
83
|
-
) -> RawChunkType:
|
|
84
|
-
bounds = dimension.bounds().bounding_box()
|
|
85
|
-
height = bounds.size_y
|
|
86
|
-
|
|
87
|
-
# Get the data version. All Java chunk classes must have this
|
|
88
|
-
data_version = chunk.get_component(DataVersionComponent)
|
|
89
|
-
game_version = get_game_version("java", VersionNumber(data_version))
|
|
90
|
-
|
|
91
|
-
# Pull out or create the raw chunk data
|
|
92
|
-
raw_chunk_component = chunk.get_component(RawChunkComponent)
|
|
93
|
-
if raw_chunk_component is None:
|
|
94
|
-
raw_chunk = {}
|
|
95
|
-
else:
|
|
96
|
-
raw_chunk = raw_chunk_component
|
|
97
|
-
|
|
98
|
-
# Set up the region and level objects
|
|
99
|
-
region = raw_chunk.setdefault("region", NamedTag()).compound
|
|
100
|
-
if data_version >= 2844:
|
|
101
|
-
# This should be unused
|
|
102
|
-
level = CompoundTag()
|
|
103
|
-
else:
|
|
104
|
-
level = region.setdefault_compound("Level")
|
|
105
|
-
|
|
106
|
-
if data_version >= 0:
|
|
107
|
-
region["DataVersion"] = IntTag(data_version)
|
|
108
|
-
else:
|
|
109
|
-
region["V"] = ByteTag(chunk.get_component(LegacyVersionComponent))
|
|
110
|
-
|
|
111
|
-
# Chunk x and y pos
|
|
112
|
-
if data_version >= 2844:
|
|
113
|
-
region["xPos"] = IntTag(cx)
|
|
114
|
-
floor_cy = bounds.min_y >> 4
|
|
115
|
-
region["yPos"] = IntTag(floor_cy)
|
|
116
|
-
ceil_cy = bounds.max_y >> 4
|
|
117
|
-
region["zPos"] = IntTag(cz)
|
|
118
|
-
else:
|
|
119
|
-
level["xPos"] = IntTag(cx)
|
|
120
|
-
floor_cy = 0
|
|
121
|
-
ceil_cy = 16
|
|
122
|
-
level["zPos"] = IntTag(cz)
|
|
123
|
-
|
|
124
|
-
# LastUpdate
|
|
125
|
-
if data_version >= 2844:
|
|
126
|
-
region["LastUpdate"] = LongTag(chunk.get_component(LastUpdateComponent))
|
|
127
|
-
region["InhabitedTime"] = LongTag(chunk.get_component(InhabitedTimeComponent))
|
|
128
|
-
else:
|
|
129
|
-
level["LastUpdate"] = LongTag(chunk.get_component(LastUpdateComponent))
|
|
130
|
-
level["InhabitedTime"] = LongTag(chunk.get_component(InhabitedTimeComponent))
|
|
131
|
-
|
|
132
|
-
# Status
|
|
133
|
-
if data_version >= 2844:
|
|
134
|
-
region["Status"] = StringTag(chunk.get_component(StatusComponent))
|
|
135
|
-
elif data_version >= 1444:
|
|
136
|
-
level["Status"] = StringTag(chunk.get_component(StatusComponent))
|
|
137
|
-
else:
|
|
138
|
-
level["TerrainPopulated"] = ByteTag(
|
|
139
|
-
chunk.get_component(TerrainPopulatedComponent)
|
|
140
|
-
)
|
|
141
|
-
level["LightPopulated"] = ByteTag(chunk.get_component(LightPopulatedComponent))
|
|
142
|
-
|
|
143
|
-
# Height map
|
|
144
|
-
if data_version >= 1466:
|
|
145
|
-
height_maps = CompoundTag(
|
|
146
|
-
{
|
|
147
|
-
key: LongArrayTag(
|
|
148
|
-
encode_long_array(
|
|
149
|
-
value.ravel() - (floor_cy << 4),
|
|
150
|
-
height.bit_length(),
|
|
151
|
-
data_version <= 2529,
|
|
152
|
-
)
|
|
153
|
-
)
|
|
154
|
-
for key, value in chunk.get_component(
|
|
155
|
-
NamedHeight2DComponent
|
|
156
|
-
).arrays.items()
|
|
157
|
-
if isinstance(key, str)
|
|
158
|
-
and isinstance(value, numpy.ndarray)
|
|
159
|
-
and value.size == 256
|
|
160
|
-
}
|
|
161
|
-
)
|
|
162
|
-
if data_version >= 2844:
|
|
163
|
-
region["HeightMaps"] = height_maps
|
|
164
|
-
else:
|
|
165
|
-
level["HeightMaps"] = height_maps
|
|
166
|
-
else:
|
|
167
|
-
level["HeightMap"] = IntArrayTag(chunk.get_component(Height2DComponent).ravel())
|
|
168
|
-
|
|
169
|
-
# biomes
|
|
170
|
-
get_biome_id_override: Callable[[str, str], int] = (
|
|
171
|
-
raw_level.biome_id_override.namespace_id_to_numerical_id
|
|
172
|
-
)
|
|
173
|
-
get_biome_id_game: Callable[[str, str], int] = (
|
|
174
|
-
game_version.biome.namespace_id_to_numerical_id
|
|
175
|
-
)
|
|
176
|
-
|
|
177
|
-
@cache
|
|
178
|
-
def encode_biome(namespace: str, base_name: str) -> int:
|
|
179
|
-
try:
|
|
180
|
-
# First try overrides
|
|
181
|
-
return get_biome_id_override(namespace, base_name)
|
|
182
|
-
except KeyError:
|
|
183
|
-
try:
|
|
184
|
-
# Then fall back to the game implementation.
|
|
185
|
-
return get_biome_id_game(namespace, base_name)
|
|
186
|
-
except KeyError:
|
|
187
|
-
log.error(
|
|
188
|
-
f"Unknown biome {namespace}:{base_name}. Falling back to default."
|
|
189
|
-
)
|
|
190
|
-
default_biome = dimension.default_biome()
|
|
191
|
-
if (
|
|
192
|
-
namespace == default_biome.namespace
|
|
193
|
-
and base_name == default_biome.base_name
|
|
194
|
-
):
|
|
195
|
-
return 0
|
|
196
|
-
return encode_biome(default_biome.namespace, default_biome.base_name)
|
|
197
|
-
|
|
198
|
-
if data_version >= 2844:
|
|
199
|
-
# region.sections[]
|
|
200
|
-
sections_tag = region.setdefault_list("sections")
|
|
201
|
-
else:
|
|
202
|
-
# region.Level.sections[]
|
|
203
|
-
sections_tag = level.setdefault_list("sections")
|
|
204
|
-
sections_map = {}
|
|
205
|
-
for section_tag in sections_tag:
|
|
206
|
-
assert isinstance(section_tag, CompoundTag)
|
|
207
|
-
sections_map[section_tag.get_byte("Y", ByteTag(0)).py_int] = section_tag
|
|
208
|
-
|
|
209
|
-
def get_section(cy_: int) -> CompoundTag:
|
|
210
|
-
section_tag_ = sections_map.get(cy_, None)
|
|
211
|
-
if section_tag_ is None:
|
|
212
|
-
section_tag_ = sections_map[cy_] = CompoundTag()
|
|
213
|
-
section_tag_["Y"] = ByteTag(cy_)
|
|
214
|
-
sections_tag.append(section_tag_)
|
|
215
|
-
return section_tag_
|
|
216
|
-
|
|
217
|
-
if data_version >= 2203:
|
|
218
|
-
# 3D
|
|
219
|
-
biome_data_3d: Biome3DComponentData = chunk.get_component(Biome3DComponent)
|
|
220
|
-
biome_sections: SubChunkArrayContainer = biome_data_3d.sections
|
|
221
|
-
palette = biome_data_3d.palette
|
|
222
|
-
if data_version >= 2836:
|
|
223
|
-
# Paletted
|
|
224
|
-
# if data_version >= 2844:
|
|
225
|
-
# # region.sections[].biomes.palette
|
|
226
|
-
# # region.sections[].biomes.data
|
|
227
|
-
# else:
|
|
228
|
-
# # region.Level.sections[].biomes.palette
|
|
229
|
-
# # region.Level.sections[].biomes.data
|
|
230
|
-
|
|
231
|
-
for cy in range(floor_cy, ceil_cy):
|
|
232
|
-
if cy not in biome_sections:
|
|
233
|
-
continue
|
|
234
|
-
arr = numpy.transpose(biome_sections[cy], (1, 2, 0)).ravel()
|
|
235
|
-
runtime_ids, arr = numpy.unique(arr, return_inverse=True)
|
|
236
|
-
sub_palette = ListTag(
|
|
237
|
-
[
|
|
238
|
-
StringTag(palette.index_to_biome(runtime_id).namespaced_name)
|
|
239
|
-
for runtime_id in runtime_ids
|
|
240
|
-
]
|
|
241
|
-
)
|
|
242
|
-
section_tag = get_section(cy)
|
|
243
|
-
biomes = section_tag["biomes"] = CompoundTag({"palette": sub_palette})
|
|
244
|
-
if len(sub_palette) > 1:
|
|
245
|
-
biomes["data"] = LongArrayTag(
|
|
246
|
-
encode_long_array(arr, dense=data_version <= 2529)
|
|
247
|
-
)
|
|
248
|
-
else:
|
|
249
|
-
# hard coded ids
|
|
250
|
-
# region.Level.Biomes (4x64x4 IntArrayTag[1024])
|
|
251
|
-
arrays = []
|
|
252
|
-
for cy in range(floor_cy, ceil_cy):
|
|
253
|
-
if cy not in biome_sections:
|
|
254
|
-
biome_sections.populate(cy)
|
|
255
|
-
arrays.append(biome_sections[cy])
|
|
256
|
-
arr = numpy.transpose(
|
|
257
|
-
numpy.stack(arrays, 1, dtype=numpy.uint32),
|
|
258
|
-
(1, 2, 0),
|
|
259
|
-
).ravel() # YZX -> XYZ
|
|
260
|
-
runtime_ids, arr = numpy.unique(arr, return_inverse=True)
|
|
261
|
-
numerical_ids = []
|
|
262
|
-
for rid in runtime_ids:
|
|
263
|
-
biome = palette.index_to_biome(rid)
|
|
264
|
-
numerical_ids.append(encode_biome(biome.namespace, biome.base_name))
|
|
265
|
-
level["Biomes"] = IntArrayTag(
|
|
266
|
-
numpy.asarray(numerical_ids, dtype=numpy.uint32)[arr]
|
|
267
|
-
)
|
|
268
|
-
else:
|
|
269
|
-
# 2D
|
|
270
|
-
biome_data_2d: Biome2DComponentData = chunk.get_component(Biome2DComponent)
|
|
271
|
-
runtime_ids, arr = numpy.unique(
|
|
272
|
-
biome_data_2d.array.ravel(), return_inverse=True
|
|
273
|
-
)
|
|
274
|
-
numerical_ids = []
|
|
275
|
-
for rid in runtime_ids:
|
|
276
|
-
biome = biome_data_2d.palette.index_to_biome(rid)
|
|
277
|
-
numerical_ids.append(encode_biome(biome.namespace, biome.base_name))
|
|
278
|
-
if data_version >= 1467:
|
|
279
|
-
# region.Level.Biomes (16x16 IntArrayTag[256])
|
|
280
|
-
level["Biomes"] = IntArrayTag(
|
|
281
|
-
numpy.asarray(numerical_ids, dtype=numpy.uint32)[arr]
|
|
282
|
-
)
|
|
283
|
-
else:
|
|
284
|
-
# region.Level.Biomes (16x16 ByteArrayTag[256])
|
|
285
|
-
level["Biomes"] = ByteArrayTag(
|
|
286
|
-
numpy.asarray(numerical_ids, dtype=numpy.uint8)[arr]
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
# blocks
|
|
290
|
-
block_component_data = chunk.get_component(BlockComponent)
|
|
291
|
-
block_palette: BlockPalette = block_component_data.palette
|
|
292
|
-
block_sections: SubChunkArrayContainer = block_component_data.sections
|
|
293
|
-
|
|
294
|
-
if data_version >= 1444:
|
|
295
|
-
# if data_version >= 2844:
|
|
296
|
-
# # region.sections[].block_states.data
|
|
297
|
-
# # region.sections[].block_states.palette
|
|
298
|
-
# elif data_version >= 2836:
|
|
299
|
-
# # region.Level.Sections[].block_states.data
|
|
300
|
-
# # region.Level.Sections[].block_states.palette
|
|
301
|
-
# else:
|
|
302
|
-
# # region.Level.Sections[].BlockStates
|
|
303
|
-
# # region.Level.Sections[].Palette
|
|
304
|
-
for cy, block_section in block_sections.items():
|
|
305
|
-
if floor_cy <= cy <= ceil_cy:
|
|
306
|
-
block_sub_array = numpy.transpose(block_section, (1, 2, 0)).ravel()
|
|
307
|
-
block_lut, block_arr = unique_inverse(block_sub_array)
|
|
308
|
-
palette_tag = ListTag[CompoundTag]()
|
|
309
|
-
for palette_index in block_lut:
|
|
310
|
-
palette_tag.append(
|
|
311
|
-
encode_block(
|
|
312
|
-
game_version,
|
|
313
|
-
block_palette.index_to_block_stack(palette_index),
|
|
314
|
-
)
|
|
315
|
-
)
|
|
316
|
-
|
|
317
|
-
section_tag = get_section(cy)
|
|
318
|
-
if data_version >= 2836:
|
|
319
|
-
section_tag["block_states"] = block_states_tag = CompoundTag(
|
|
320
|
-
{"palette": palette_tag}
|
|
321
|
-
)
|
|
322
|
-
if len(palette_tag) > 1:
|
|
323
|
-
block_states_tag["data"] = LongArrayTag(
|
|
324
|
-
encode_long_array(
|
|
325
|
-
block_sub_array,
|
|
326
|
-
dense=data_version <= 2529,
|
|
327
|
-
min_bits_per_entry=4,
|
|
328
|
-
)
|
|
329
|
-
)
|
|
330
|
-
else:
|
|
331
|
-
section_tag["Palette"] = palette_tag
|
|
332
|
-
section_tag["BlockStates"] = LongArrayTag(
|
|
333
|
-
encode_long_array(
|
|
334
|
-
block_sub_array,
|
|
335
|
-
dense=data_version <= 2529,
|
|
336
|
-
min_bits_per_entry=4,
|
|
337
|
-
)
|
|
338
|
-
)
|
|
339
|
-
else:
|
|
340
|
-
# region.Level.Sections[].Blocks
|
|
341
|
-
# region.Level.Sections[].Add
|
|
342
|
-
# region.Level.Sections[].Data
|
|
343
|
-
get_block_id_override = raw_level.block_id_override.namespace_id_to_numerical_id
|
|
344
|
-
get_block_id_game = game_version.block.namespace_id_to_numerical_id
|
|
345
|
-
block_ids = []
|
|
346
|
-
block_datas = []
|
|
347
|
-
for block_stack in block_palette:
|
|
348
|
-
block = block_stack[0]
|
|
349
|
-
namespace = block.namespace
|
|
350
|
-
base_name = block.base_name
|
|
351
|
-
try:
|
|
352
|
-
block_id = get_block_id_override(namespace, base_name)
|
|
353
|
-
except KeyError:
|
|
354
|
-
try:
|
|
355
|
-
block_id = get_block_id_game(namespace, base_name)
|
|
356
|
-
except KeyError:
|
|
357
|
-
if namespace == "numerical" and base_name.isnumeric():
|
|
358
|
-
block_id = int(base_name) & 255
|
|
359
|
-
else:
|
|
360
|
-
block_id = 0
|
|
361
|
-
|
|
362
|
-
block_data_tag = block.properties.get("block_data")
|
|
363
|
-
if isinstance(block_data_tag, AbstractBaseIntTag):
|
|
364
|
-
block_data = block_data_tag.py_int & 15
|
|
365
|
-
else:
|
|
366
|
-
block_data = 0
|
|
367
|
-
block_ids.append(block_id)
|
|
368
|
-
block_datas.append(block_data)
|
|
369
|
-
block_id_array = numpy.array(block_ids, dtype=numpy.uint8)
|
|
370
|
-
block_data_array = numpy.array(block_datas, dtype=numpy.uint8)
|
|
371
|
-
|
|
372
|
-
for cy, block_section in block_sections.items():
|
|
373
|
-
if 0 <= cy <= 16:
|
|
374
|
-
flat_block_section = numpy.transpose(
|
|
375
|
-
block_section, (1, 2, 0)
|
|
376
|
-
).ravel() # XYZ -> YZX
|
|
377
|
-
section_tag = get_section(cy)
|
|
378
|
-
section_tag["Blocks"] = ByteArrayTag(block_id_array[flat_block_section])
|
|
379
|
-
section_tag["Data"] = ByteArrayTag(
|
|
380
|
-
to_nibble_array(block_data_array[flat_block_section])
|
|
381
|
-
)
|
|
382
|
-
|
|
383
|
-
# block entities
|
|
384
|
-
block_entities = ListTag[CompoundTag]()
|
|
385
|
-
block_entity: BlockEntity
|
|
386
|
-
for (x, y, z), block_entity in chunk.get_component(BlockEntityComponent).items():
|
|
387
|
-
tag = block_entity.nbt.compound
|
|
388
|
-
tag["id"] = StringTag(block_entity.namespaced_name)
|
|
389
|
-
tag["x"] = IntTag(x)
|
|
390
|
-
tag["y"] = IntTag(y)
|
|
391
|
-
tag["z"] = IntTag(z)
|
|
392
|
-
block_entities.append(tag)
|
|
393
|
-
if data_version >= 2844:
|
|
394
|
-
# region.block_entities
|
|
395
|
-
region["block_entities"] = block_entities
|
|
396
|
-
else:
|
|
397
|
-
# region.Level.TileEntities
|
|
398
|
-
level["TileEntities"] = block_entities
|
|
399
|
-
|
|
400
|
-
# entities
|
|
401
|
-
entities = ListTag[CompoundTag]()
|
|
402
|
-
entity: Entity
|
|
403
|
-
for entity in chunk.get_component(EntityComponent):
|
|
404
|
-
tag = entity.nbt.compound
|
|
405
|
-
tag["id"] = StringTag(entity.namespaced_name)
|
|
406
|
-
tag["Pos"] = ListTag(
|
|
407
|
-
[DoubleTag(entity.x), DoubleTag(entity.y), DoubleTag(entity.z)]
|
|
408
|
-
)
|
|
409
|
-
entities.append(tag)
|
|
410
|
-
if data_version >= 2681:
|
|
411
|
-
# entities.Entities
|
|
412
|
-
entity_layer = raw_chunk.setdefault("entities", NamedTag()).compound
|
|
413
|
-
entity_layer["Entities"] = entities
|
|
414
|
-
else:
|
|
415
|
-
# region.Level.Entities
|
|
416
|
-
level["Entities"] = entities
|
|
417
|
-
|
|
418
|
-
if 1519 <= data_version < 1901:
|
|
419
|
-
# all defined sections must have the BlockStates and Palette fields
|
|
420
|
-
for section in sections_map.values():
|
|
421
|
-
if "Palette" in section:
|
|
422
|
-
if "BlockStates" not in section:
|
|
423
|
-
assert len(section.get_list("Palette", raise_errors=True)) == 1
|
|
424
|
-
section["BlockStates"] = LongArrayTag([0] * 256)
|
|
425
|
-
else:
|
|
426
|
-
section["Palette"] = ListTag(
|
|
427
|
-
[CompoundTag({"Name": StringTag("minecraft:air")})]
|
|
428
|
-
)
|
|
429
|
-
section["BlockStates"] = LongArrayTag([0] * 256)
|
|
430
|
-
|
|
431
|
-
if data_version < 1934:
|
|
432
|
-
# BlockLight and SkyLight are required
|
|
433
|
-
for section_tag in sections_map.values():
|
|
434
|
-
for key in ("BlockLight", "SkyLight"):
|
|
435
|
-
if key not in section_tag:
|
|
436
|
-
section_tag[key] = ByteArrayTag(
|
|
437
|
-
numpy.full(2048, 255, dtype=numpy.uint8)
|
|
438
|
-
)
|
|
439
|
-
|
|
440
|
-
return raw_chunk
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
def encode_block(game_version: JavaGameVersion, block_stack: BlockStack) -> CompoundTag:
|
|
444
|
-
base_block = block_stack[0]
|
|
445
|
-
namespace = base_block.namespace
|
|
446
|
-
base_name = base_block.base_name
|
|
447
|
-
properties = dict(base_block.properties)
|
|
448
|
-
block_tag = CompoundTag({"Name": StringTag(f"{namespace}:{base_name}")})
|
|
449
|
-
if game_version.block.waterloggable(namespace, base_name) == Waterloggable.Yes:
|
|
450
|
-
if (
|
|
451
|
-
len(block_stack) >= 2
|
|
452
|
-
and block_stack[1].namespaced_name == "minecraft:water"
|
|
453
|
-
):
|
|
454
|
-
properties["waterlogged"] = StringTag("true")
|
|
455
|
-
else:
|
|
456
|
-
properties["waterlogged"] = StringTag("false")
|
|
457
|
-
if properties:
|
|
458
|
-
string_properties = {
|
|
459
|
-
k: v for k, v in properties.items() if isinstance(v, StringTag)
|
|
460
|
-
}
|
|
461
|
-
if string_properties:
|
|
462
|
-
block_tag["Properties"] = CompoundTag(string_properties)
|
|
463
|
-
return block_tag
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import amulet.selection.group
|
|
4
|
-
from amulet.selection.box import SelectionBox
|
|
5
|
-
from amulet.selection.group import SelectionGroup
|
|
6
|
-
|
|
7
|
-
__all__ = [
|
|
8
|
-
"DefaultSelection",
|
|
9
|
-
"OVERWORLD",
|
|
10
|
-
"SelectionBox",
|
|
11
|
-
"SelectionGroup",
|
|
12
|
-
"THE_END",
|
|
13
|
-
"THE_NETHER",
|
|
14
|
-
]
|
|
15
|
-
DefaultSelection: (
|
|
16
|
-
amulet.selection.group.SelectionGroup
|
|
17
|
-
) # value = SelectionGroup([SelectionBox((-30000000, 0, -30000000), (30000000, 256, 30000000))])
|
|
18
|
-
OVERWORLD: str
|
|
19
|
-
THE_END: str
|
|
20
|
-
THE_NETHER: str
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from amulet.level.java._raw._data_pack.data_pack import DataPack
|
|
4
|
-
from amulet.level.java._raw._data_pack.data_pack_manager import DataPackManager
|
|
5
|
-
|
|
6
|
-
from . import data_pack, data_pack_manager
|
|
7
|
-
|
|
8
|
-
__all__ = ["DataPack", "DataPackManager", "data_pack", "data_pack_manager"]
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import abc
|
|
4
|
-
import json as json
|
|
5
|
-
import os as os
|
|
6
|
-
import re as re
|
|
7
|
-
import typing
|
|
8
|
-
from abc import ABC, abstractmethod
|
|
9
|
-
from builtins import traceback as TracebackType
|
|
10
|
-
from typing import Protocol
|
|
11
|
-
from zipfile import ZipFile
|
|
12
|
-
|
|
13
|
-
__all__ = [
|
|
14
|
-
"ABC",
|
|
15
|
-
"BaseWrapper",
|
|
16
|
-
"DataPack",
|
|
17
|
-
"DirWrapper",
|
|
18
|
-
"Protocol",
|
|
19
|
-
"Readable",
|
|
20
|
-
"TracebackType",
|
|
21
|
-
"ZipFile",
|
|
22
|
-
"ZipWrapper",
|
|
23
|
-
"abstractmethod",
|
|
24
|
-
"json",
|
|
25
|
-
"os",
|
|
26
|
-
"re",
|
|
27
|
-
]
|
|
28
|
-
|
|
29
|
-
class BaseWrapper(abc.ABC):
|
|
30
|
-
@staticmethod
|
|
31
|
-
def is_valid(path: str) -> bool:
|
|
32
|
-
"""
|
|
33
|
-
|
|
34
|
-
Is the given path valid for this class.
|
|
35
|
-
|
|
36
|
-
:param path: The path to test.
|
|
37
|
-
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
|
-
def __init__(self, path: str): ...
|
|
41
|
-
def all_files_match(self, match: str) -> typing.Iterable[str]:
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
The relative paths of all files contained within that match the given regex.
|
|
45
|
-
|
|
46
|
-
:param match: The regex string to match again.
|
|
47
|
-
:return: An iterable of file paths that match the given regex.
|
|
48
|
-
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
def close(self) -> None:
|
|
52
|
-
"""
|
|
53
|
-
Close the contents.
|
|
54
|
-
"""
|
|
55
|
-
|
|
56
|
-
def has_file(self, relative_path: str) -> bool:
|
|
57
|
-
"""
|
|
58
|
-
|
|
59
|
-
Does the requested file exist.
|
|
60
|
-
|
|
61
|
-
:param relative_path:
|
|
62
|
-
:return:
|
|
63
|
-
|
|
64
|
-
"""
|
|
65
|
-
|
|
66
|
-
def open(self, relative_path: str) -> Readable:
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
Get the contents of the file.
|
|
70
|
-
|
|
71
|
-
:param relative_path:
|
|
72
|
-
:return:
|
|
73
|
-
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
@property
|
|
77
|
-
def all_files(self) -> typing.Iterable[str]:
|
|
78
|
-
"""
|
|
79
|
-
|
|
80
|
-
The relative paths of all files contained within.
|
|
81
|
-
|
|
82
|
-
:return: An iterable of paths.
|
|
83
|
-
|
|
84
|
-
"""
|
|
85
|
-
|
|
86
|
-
@property
|
|
87
|
-
def path(self) -> str:
|
|
88
|
-
"""
|
|
89
|
-
The path to the data.
|
|
90
|
-
"""
|
|
91
|
-
|
|
92
|
-
class DataPack:
|
|
93
|
-
"""
|
|
94
|
-
The DataPack class wraps a single data pack.
|
|
95
|
-
"""
|
|
96
|
-
|
|
97
|
-
@staticmethod
|
|
98
|
-
def is_path_valid(path: str) -> bool:
|
|
99
|
-
"""
|
|
100
|
-
|
|
101
|
-
Check if the given path is a valid data pack.
|
|
102
|
-
|
|
103
|
-
:param path: The path to the data pack. Can be a zip file or directory.
|
|
104
|
-
:return: True if the path is a valid data pack, False otherwise.
|
|
105
|
-
|
|
106
|
-
"""
|
|
107
|
-
|
|
108
|
-
@staticmethod
|
|
109
|
-
def is_wrapper_valid(wrapper: BaseWrapper) -> bool: ...
|
|
110
|
-
def __init__(self, path: str): ...
|
|
111
|
-
def all_files_match(self, match: str) -> typing.Iterable[str]:
|
|
112
|
-
"""
|
|
113
|
-
|
|
114
|
-
The relative paths of all files contained within that match the given regex.
|
|
115
|
-
|
|
116
|
-
:param match: The regex string to match again.
|
|
117
|
-
:return: An iterable of file paths that match the given regex.
|
|
118
|
-
|
|
119
|
-
"""
|
|
120
|
-
|
|
121
|
-
def close(self) -> None:
|
|
122
|
-
"""
|
|
123
|
-
Close the contents.
|
|
124
|
-
"""
|
|
125
|
-
|
|
126
|
-
def has_file(self, relative_path: str) -> bool:
|
|
127
|
-
"""
|
|
128
|
-
|
|
129
|
-
Does the requested file exist.
|
|
130
|
-
|
|
131
|
-
:param relative_path:
|
|
132
|
-
:return:
|
|
133
|
-
|
|
134
|
-
"""
|
|
135
|
-
|
|
136
|
-
def open(self, relative_path: str) -> Readable:
|
|
137
|
-
"""
|
|
138
|
-
|
|
139
|
-
Get the contents of the file.
|
|
140
|
-
|
|
141
|
-
:param relative_path:
|
|
142
|
-
:return:
|
|
143
|
-
|
|
144
|
-
"""
|
|
145
|
-
|
|
146
|
-
@property
|
|
147
|
-
def all_files(self) -> typing.Iterable[str]:
|
|
148
|
-
"""
|
|
149
|
-
|
|
150
|
-
The relative paths of all files contained within.
|
|
151
|
-
|
|
152
|
-
:return: An iterable of paths.
|
|
153
|
-
|
|
154
|
-
"""
|
|
155
|
-
|
|
156
|
-
@property
|
|
157
|
-
def is_valid(self) -> bool: ...
|
|
158
|
-
@property
|
|
159
|
-
def path(self) -> str:
|
|
160
|
-
"""
|
|
161
|
-
The path to the data.
|
|
162
|
-
"""
|
|
163
|
-
|
|
164
|
-
class DirWrapper(BaseWrapper):
|
|
165
|
-
@staticmethod
|
|
166
|
-
def is_valid(path: str) -> bool: ...
|
|
167
|
-
def __init__(self, path: str): ...
|
|
168
|
-
def close(self) -> None: ...
|
|
169
|
-
def has_file(self, relative_path: str) -> bool: ...
|
|
170
|
-
def open(self, relative_path: str) -> Readable: ...
|
|
171
|
-
@property
|
|
172
|
-
def all_files(self) -> typing.Iterable[str]: ...
|
|
173
|
-
|
|
174
|
-
class Readable(typing.Protocol):
|
|
175
|
-
@classmethod
|
|
176
|
-
def __subclasshook__(cls, other): ...
|
|
177
|
-
def __enter__(self) -> Readable: ...
|
|
178
|
-
def __exit__(
|
|
179
|
-
self,
|
|
180
|
-
exc_type: type[BaseException] | None,
|
|
181
|
-
exc_val: BaseException | None,
|
|
182
|
-
exc_tb: TracebackType | None,
|
|
183
|
-
) -> None: ...
|
|
184
|
-
def __init__(self, *args, **kwargs): ...
|
|
185
|
-
def read(self, n: int = -1) -> bytes: ...
|
|
186
|
-
|
|
187
|
-
class ZipWrapper(BaseWrapper):
|
|
188
|
-
@staticmethod
|
|
189
|
-
def is_valid(path: str) -> bool: ...
|
|
190
|
-
def __init__(self, path: str): ...
|
|
191
|
-
def close(self) -> None: ...
|
|
192
|
-
def has_file(self, relative_path: str) -> bool: ...
|
|
193
|
-
def open(self, name: str) -> Readable: ...
|
|
194
|
-
@property
|
|
195
|
-
def all_files(self) -> typing.Iterable[str]: ...
|
|
196
|
-
|
|
197
|
-
def _open_wrapper(path: str) -> BaseWrapper: ...
|