amulet-core 2.0a5__cp312-cp312-macosx_10_13_universal2.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__.cpython-312-darwin.so +0 -0
- amulet/__init__.pyi +30 -0
- amulet/__pyinstaller/__init__.py +2 -0
- amulet/__pyinstaller/hook-amulet.py +4 -0
- amulet/_init.py +28 -0
- amulet/_version.py +21 -0
- amulet/biome.cpp +36 -0
- amulet/biome.hpp +43 -0
- amulet/biome.pyi +77 -0
- amulet/block.cpp +435 -0
- amulet/block.hpp +119 -0
- amulet/block.pyi +273 -0
- amulet/block_entity.cpp +12 -0
- amulet/block_entity.hpp +56 -0
- amulet/block_entity.pyi +80 -0
- amulet/chunk.cpp +16 -0
- amulet/chunk.hpp +99 -0
- amulet/chunk.pyi +30 -0
- amulet/chunk_/components/biome.py +155 -0
- amulet/chunk_/components/block_entity.py +117 -0
- amulet/chunk_/components/entity.py +64 -0
- amulet/chunk_/components/height_2d.py +16 -0
- amulet/chunk_components.pyi +95 -0
- amulet/collections.pyi +37 -0
- amulet/data_types.py +29 -0
- amulet/entity.py +180 -0
- amulet/errors.py +63 -0
- amulet/game/__init__.py +7 -0
- amulet/game/_game.py +152 -0
- amulet/game/_universal/__init__.py +1 -0
- amulet/game/_universal/_biome.py +17 -0
- amulet/game/_universal/_block.py +47 -0
- amulet/game/_universal/_version.py +68 -0
- amulet/game/abc/__init__.py +22 -0
- amulet/game/abc/_block_specification.py +150 -0
- amulet/game/abc/biome.py +213 -0
- amulet/game/abc/block.py +331 -0
- amulet/game/abc/game_version_container.py +25 -0
- amulet/game/abc/json_interface.py +27 -0
- amulet/game/abc/version.py +44 -0
- amulet/game/bedrock/__init__.py +1 -0
- amulet/game/bedrock/_biome.py +35 -0
- amulet/game/bedrock/_block.py +42 -0
- amulet/game/bedrock/_version.py +165 -0
- amulet/game/java/__init__.py +2 -0
- amulet/game/java/_biome.py +35 -0
- amulet/game/java/_block.py +60 -0
- amulet/game/java/_version.py +176 -0
- amulet/game/translate/__init__.py +12 -0
- amulet/game/translate/_functions/__init__.py +15 -0
- amulet/game/translate/_functions/_code_functions/__init__.py +0 -0
- amulet/game/translate/_functions/_code_functions/_text.py +553 -0
- amulet/game/translate/_functions/_code_functions/banner_pattern.py +67 -0
- amulet/game/translate/_functions/_code_functions/bedrock_chest_connection.py +152 -0
- amulet/game/translate/_functions/_code_functions/bedrock_moving_block_pos.py +88 -0
- amulet/game/translate/_functions/_code_functions/bedrock_sign.py +152 -0
- amulet/game/translate/_functions/_code_functions/bedrock_skull_rotation.py +16 -0
- amulet/game/translate/_functions/_code_functions/custom_name.py +146 -0
- amulet/game/translate/_functions/_frozen.py +66 -0
- amulet/game/translate/_functions/_state.py +54 -0
- amulet/game/translate/_functions/_typing.py +98 -0
- amulet/game/translate/_functions/abc.py +116 -0
- amulet/game/translate/_functions/carry_nbt.py +160 -0
- amulet/game/translate/_functions/carry_properties.py +80 -0
- amulet/game/translate/_functions/code.py +143 -0
- amulet/game/translate/_functions/map_block_name.py +66 -0
- amulet/game/translate/_functions/map_nbt.py +111 -0
- amulet/game/translate/_functions/map_properties.py +93 -0
- amulet/game/translate/_functions/multiblock.py +112 -0
- amulet/game/translate/_functions/new_block.py +42 -0
- amulet/game/translate/_functions/new_entity.py +43 -0
- amulet/game/translate/_functions/new_nbt.py +206 -0
- amulet/game/translate/_functions/new_properties.py +64 -0
- amulet/game/translate/_functions/sequence.py +51 -0
- amulet/game/translate/_functions/walk_input_nbt.py +331 -0
- amulet/game/translate/_translator.py +433 -0
- amulet/item.py +75 -0
- amulet/level/__init__.pyi +27 -0
- amulet/level/_load.py +100 -0
- amulet/level/abc/__init__.py +12 -0
- amulet/level/abc/_chunk_handle.py +335 -0
- amulet/level/abc/_dimension.py +86 -0
- amulet/level/abc/_history/__init__.py +1 -0
- amulet/level/abc/_history/_cache.py +224 -0
- amulet/level/abc/_history/_history_manager.py +291 -0
- amulet/level/abc/_level/__init__.py +5 -0
- amulet/level/abc/_level/_compactable_level.py +10 -0
- amulet/level/abc/_level/_creatable_level.py +29 -0
- amulet/level/abc/_level/_disk_level.py +17 -0
- amulet/level/abc/_level/_level.py +453 -0
- amulet/level/abc/_level/_loadable_level.py +42 -0
- amulet/level/abc/_player_storage.py +7 -0
- amulet/level/abc/_raw_level.py +187 -0
- amulet/level/abc/_registry.py +40 -0
- amulet/level/bedrock/__init__.py +2 -0
- amulet/level/bedrock/_chunk_handle.py +19 -0
- amulet/level/bedrock/_dimension.py +22 -0
- amulet/level/bedrock/_level.py +187 -0
- amulet/level/bedrock/_raw/__init__.py +5 -0
- amulet/level/bedrock/_raw/_actor_counter.py +53 -0
- amulet/level/bedrock/_raw/_chunk.py +54 -0
- amulet/level/bedrock/_raw/_chunk_decode.py +668 -0
- amulet/level/bedrock/_raw/_chunk_encode.py +602 -0
- amulet/level/bedrock/_raw/_constant.py +9 -0
- amulet/level/bedrock/_raw/_dimension.py +343 -0
- amulet/level/bedrock/_raw/_level.py +463 -0
- amulet/level/bedrock/_raw/_level_dat.py +90 -0
- amulet/level/bedrock/_raw/_typing.py +6 -0
- amulet/level/bedrock/_raw/leveldb_chunk_versions.py +83 -0
- amulet/level/bedrock/chunk/__init__.py +1 -0
- amulet/level/bedrock/chunk/_chunk.py +126 -0
- amulet/level/bedrock/chunk/components/__init__.py +0 -0
- amulet/level/bedrock/chunk/components/chunk_version.py +12 -0
- amulet/level/bedrock/chunk/components/finalised_state.py +13 -0
- amulet/level/bedrock/chunk/components/raw_chunk.py +15 -0
- amulet/level/construction/__init__.py +0 -0
- amulet/level/java/__init__.pyi +21 -0
- amulet/level/java/_chunk_handle.py +17 -0
- amulet/level/java/_chunk_handle.pyi +15 -0
- amulet/level/java/_dimension.py +20 -0
- amulet/level/java/_dimension.pyi +13 -0
- amulet/level/java/_level.py +184 -0
- amulet/level/java/_level.pyi +120 -0
- amulet/level/java/_raw/__init__.pyi +19 -0
- amulet/level/java/_raw/_chunk.pyi +23 -0
- amulet/level/java/_raw/_chunk_decode.py +561 -0
- amulet/level/java/_raw/_chunk_encode.py +463 -0
- amulet/level/java/_raw/_constant.py +9 -0
- amulet/level/java/_raw/_constant.pyi +20 -0
- amulet/level/java/_raw/_data_pack/__init__.py +2 -0
- amulet/level/java/_raw/_data_pack/__init__.pyi +8 -0
- amulet/level/java/_raw/_data_pack/data_pack.py +241 -0
- amulet/level/java/_raw/_data_pack/data_pack.pyi +197 -0
- amulet/level/java/_raw/_data_pack/data_pack_manager.py +77 -0
- amulet/level/java/_raw/_data_pack/data_pack_manager.pyi +75 -0
- amulet/level/java/_raw/_dimension.py +86 -0
- amulet/level/java/_raw/_dimension.pyi +72 -0
- amulet/level/java/_raw/_level.py +507 -0
- amulet/level/java/_raw/_level.pyi +238 -0
- amulet/level/java/_raw/_typing.py +3 -0
- amulet/level/java/_raw/_typing.pyi +5 -0
- amulet/level/java/anvil/__init__.py +2 -0
- amulet/level/java/anvil/__init__.pyi +11 -0
- amulet/level/java/anvil/_dimension.py +170 -0
- amulet/level/java/anvil/_dimension.pyi +109 -0
- amulet/level/java/anvil/_region.py +421 -0
- amulet/level/java/anvil/_region.pyi +197 -0
- amulet/level/java/anvil/_sector_manager.py +223 -0
- amulet/level/java/anvil/_sector_manager.pyi +142 -0
- amulet/level/java/chunk.pyi +81 -0
- amulet/level/java/chunk_/_chunk.py +260 -0
- amulet/level/java/chunk_/components/inhabited_time.py +12 -0
- amulet/level/java/chunk_/components/last_update.py +12 -0
- amulet/level/java/chunk_/components/legacy_version.py +12 -0
- amulet/level/java/chunk_/components/light_populated.py +12 -0
- amulet/level/java/chunk_/components/named_height_2d.py +37 -0
- amulet/level/java/chunk_/components/status.py +11 -0
- amulet/level/java/chunk_/components/terrain_populated.py +12 -0
- amulet/level/java/chunk_components.pyi +22 -0
- amulet/level/java/long_array.pyi +38 -0
- 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/level/temporary_level/__init__.py +1 -0
- amulet/level/temporary_level/_level.py +16 -0
- amulet/palette/__init__.pyi +8 -0
- amulet/palette/biome_palette.pyi +45 -0
- amulet/palette/block_palette.pyi +45 -0
- amulet/player.py +64 -0
- amulet/py.typed +0 -0
- amulet/selection/__init__.py +2 -0
- amulet/selection/abstract_selection.py +342 -0
- amulet/selection/box.py +852 -0
- amulet/selection/group.py +481 -0
- amulet/utils/__init__.pyi +28 -0
- amulet/utils/call_spec/__init__.py +24 -0
- amulet/utils/call_spec/__init__.pyi +53 -0
- amulet/utils/call_spec/_call_spec.py +262 -0
- amulet/utils/call_spec/_call_spec.pyi +272 -0
- amulet/utils/format_utils.py +41 -0
- amulet/utils/generator.py +18 -0
- amulet/utils/matrix.py +243 -0
- amulet/utils/matrix.pyi +177 -0
- amulet/utils/numpy.pyi +11 -0
- amulet/utils/numpy_helpers.py +19 -0
- amulet/utils/shareable_lock.py +335 -0
- amulet/utils/shareable_lock.pyi +190 -0
- amulet/utils/signal/__init__.py +10 -0
- amulet/utils/signal/__init__.pyi +25 -0
- amulet/utils/signal/_signal.py +228 -0
- amulet/utils/signal/_signal.pyi +84 -0
- amulet/utils/task_manager.py +235 -0
- amulet/utils/task_manager.pyi +168 -0
- amulet/utils/typed_property.py +111 -0
- amulet/utils/typing.py +4 -0
- amulet/utils/typing.pyi +6 -0
- amulet/utils/weakref.py +70 -0
- amulet/utils/weakref.pyi +50 -0
- amulet/utils/world_utils.py +102 -0
- amulet/utils/world_utils.pyi +109 -0
- amulet/version.cpp +136 -0
- amulet/version.hpp +142 -0
- amulet/version.pyi +94 -0
- amulet_core-2.0a5.dist-info/METADATA +103 -0
- amulet_core-2.0a5.dist-info/RECORD +210 -0
- amulet_core-2.0a5.dist-info/WHEEL +5 -0
- amulet_core-2.0a5.dist-info/entry_points.txt +2 -0
- amulet_core-2.0a5.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from abc import ABC, abstractmethod
|
|
3
|
+
from typing import Iterable, Protocol
|
|
4
|
+
from types import TracebackType
|
|
5
|
+
import os
|
|
6
|
+
import json
|
|
7
|
+
from zipfile import ZipFile
|
|
8
|
+
import re
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Readable(Protocol):
|
|
12
|
+
def read(self, n: int = -1) -> bytes: ...
|
|
13
|
+
|
|
14
|
+
def __enter__(self) -> Readable: ...
|
|
15
|
+
|
|
16
|
+
def __exit__(
|
|
17
|
+
self,
|
|
18
|
+
exc_type: type[BaseException] | None,
|
|
19
|
+
exc_val: BaseException | None,
|
|
20
|
+
exc_tb: TracebackType | None,
|
|
21
|
+
) -> None: ...
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class BaseWrapper(ABC):
|
|
25
|
+
def __init__(self, path: str):
|
|
26
|
+
self._path = path
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
@abstractmethod
|
|
30
|
+
def is_valid(path: str) -> bool:
|
|
31
|
+
"""
|
|
32
|
+
Is the given path valid for this class.
|
|
33
|
+
|
|
34
|
+
:param path: The path to test.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def path(self) -> str:
|
|
39
|
+
"""The path to the data."""
|
|
40
|
+
return self._path
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
@abstractmethod
|
|
44
|
+
def all_files(self) -> Iterable[str]:
|
|
45
|
+
"""
|
|
46
|
+
The relative paths of all files contained within.
|
|
47
|
+
|
|
48
|
+
:return: An iterable of paths.
|
|
49
|
+
"""
|
|
50
|
+
raise NotImplementedError
|
|
51
|
+
|
|
52
|
+
def all_files_match(self, match: str) -> Iterable[str]:
|
|
53
|
+
"""
|
|
54
|
+
The relative paths of all files contained within that match the given regex.
|
|
55
|
+
|
|
56
|
+
:param match: The regex string to match again.
|
|
57
|
+
:return: An iterable of file paths that match the given regex.
|
|
58
|
+
"""
|
|
59
|
+
re_match = re.compile(match)
|
|
60
|
+
return tuple(path for path in self.all_files if re_match.fullmatch(path))
|
|
61
|
+
|
|
62
|
+
@abstractmethod
|
|
63
|
+
def has_file(self, relative_path: str) -> bool:
|
|
64
|
+
"""
|
|
65
|
+
Does the requested file exist.
|
|
66
|
+
|
|
67
|
+
:param relative_path:
|
|
68
|
+
:return:
|
|
69
|
+
"""
|
|
70
|
+
raise NotImplementedError
|
|
71
|
+
|
|
72
|
+
@abstractmethod
|
|
73
|
+
def open(self, relative_path: str) -> Readable:
|
|
74
|
+
"""
|
|
75
|
+
Get the contents of the file.
|
|
76
|
+
|
|
77
|
+
:param relative_path:
|
|
78
|
+
:return:
|
|
79
|
+
"""
|
|
80
|
+
raise NotImplementedError
|
|
81
|
+
|
|
82
|
+
@abstractmethod
|
|
83
|
+
def close(self) -> None:
|
|
84
|
+
"""Close the contents."""
|
|
85
|
+
raise NotImplementedError
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class ZipWrapper(BaseWrapper):
|
|
89
|
+
def __init__(self, path: str):
|
|
90
|
+
BaseWrapper.__init__(self, path)
|
|
91
|
+
self._zip_file = ZipFile(path)
|
|
92
|
+
|
|
93
|
+
@staticmethod
|
|
94
|
+
def is_valid(path: str) -> bool:
|
|
95
|
+
return os.path.isfile(path) and path.endswith(".zip")
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def all_files(self) -> Iterable[str]:
|
|
99
|
+
for path in self._zip_file.NameToInfo:
|
|
100
|
+
if not path.endswith("/"):
|
|
101
|
+
yield path
|
|
102
|
+
|
|
103
|
+
def has_file(self, relative_path: str) -> bool:
|
|
104
|
+
if relative_path.endswith("/"):
|
|
105
|
+
# is a directory
|
|
106
|
+
return False
|
|
107
|
+
else:
|
|
108
|
+
return relative_path in self._zip_file.NameToInfo
|
|
109
|
+
|
|
110
|
+
def open(self, name: str) -> Readable:
|
|
111
|
+
return self._zip_file.open(name)
|
|
112
|
+
|
|
113
|
+
def close(self) -> None:
|
|
114
|
+
self._zip_file.close()
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class DirWrapper(BaseWrapper):
|
|
118
|
+
def __init__(self, path: str):
|
|
119
|
+
BaseWrapper.__init__(self, path)
|
|
120
|
+
|
|
121
|
+
@staticmethod
|
|
122
|
+
def is_valid(path: str) -> bool:
|
|
123
|
+
return os.path.isdir(path)
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def all_files(self) -> Iterable[str]:
|
|
127
|
+
for abs_path, _, files in os.walk(self.path):
|
|
128
|
+
rel_path = os.path.normpath(os.path.relpath(abs_path, self.path)).replace(
|
|
129
|
+
os.sep, "/"
|
|
130
|
+
)
|
|
131
|
+
if rel_path == ".":
|
|
132
|
+
yield from files
|
|
133
|
+
else:
|
|
134
|
+
for f in files:
|
|
135
|
+
yield f"{rel_path}/{f}"
|
|
136
|
+
|
|
137
|
+
def has_file(self, relative_path: str) -> bool:
|
|
138
|
+
return os.path.isfile(os.path.join(self.path, relative_path))
|
|
139
|
+
|
|
140
|
+
def open(self, relative_path: str) -> Readable:
|
|
141
|
+
return open(os.path.join(self.path, relative_path), "rb")
|
|
142
|
+
|
|
143
|
+
def close(self) -> None:
|
|
144
|
+
pass
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _open_wrapper(path: str) -> BaseWrapper:
|
|
148
|
+
for cls in (ZipWrapper, DirWrapper):
|
|
149
|
+
if cls.is_valid(path):
|
|
150
|
+
return cls(path)
|
|
151
|
+
raise FileNotFoundError(f"The given path {path} is not valid.")
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class DataPack:
|
|
155
|
+
"""The DataPack class wraps a single data pack."""
|
|
156
|
+
|
|
157
|
+
def __init__(self, path: str):
|
|
158
|
+
self._path = path
|
|
159
|
+
self._wrapper = _open_wrapper(path)
|
|
160
|
+
self._is_valid = self.is_wrapper_valid(self._wrapper)
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def path(self) -> str:
|
|
164
|
+
"""The path to the data."""
|
|
165
|
+
return self._path
|
|
166
|
+
|
|
167
|
+
@staticmethod
|
|
168
|
+
def is_path_valid(path: str) -> bool:
|
|
169
|
+
"""
|
|
170
|
+
Check if the given path is a valid data pack.
|
|
171
|
+
|
|
172
|
+
:param path: The path to the data pack. Can be a zip file or directory.
|
|
173
|
+
:return: True if the path is a valid data pack, False otherwise.
|
|
174
|
+
"""
|
|
175
|
+
try:
|
|
176
|
+
wrapper = _open_wrapper(path)
|
|
177
|
+
except FileNotFoundError:
|
|
178
|
+
return False
|
|
179
|
+
is_valid = DataPack.is_wrapper_valid(wrapper)
|
|
180
|
+
wrapper.close()
|
|
181
|
+
return is_valid
|
|
182
|
+
|
|
183
|
+
@property
|
|
184
|
+
def is_valid(self) -> bool:
|
|
185
|
+
return self._is_valid
|
|
186
|
+
|
|
187
|
+
@staticmethod
|
|
188
|
+
def is_wrapper_valid(wrapper: BaseWrapper) -> bool:
|
|
189
|
+
if wrapper.has_file("pack.mcmeta"):
|
|
190
|
+
with wrapper.open("pack.mcmeta") as m:
|
|
191
|
+
try:
|
|
192
|
+
meta_file = json.load(m)
|
|
193
|
+
except json.JSONDecodeError:
|
|
194
|
+
pass
|
|
195
|
+
else:
|
|
196
|
+
if isinstance(meta_file, dict) and isinstance(
|
|
197
|
+
meta_file.get("pack", {}).get("pack_format", None), int
|
|
198
|
+
):
|
|
199
|
+
# TODO: check the actual value
|
|
200
|
+
return True
|
|
201
|
+
return False
|
|
202
|
+
|
|
203
|
+
@property
|
|
204
|
+
def all_files(self) -> Iterable[str]:
|
|
205
|
+
"""
|
|
206
|
+
The relative paths of all files contained within.
|
|
207
|
+
|
|
208
|
+
:return: An iterable of paths.
|
|
209
|
+
"""
|
|
210
|
+
return self._wrapper.all_files
|
|
211
|
+
|
|
212
|
+
def all_files_match(self, match: str) -> Iterable[str]:
|
|
213
|
+
"""
|
|
214
|
+
The relative paths of all files contained within that match the given regex.
|
|
215
|
+
|
|
216
|
+
:param match: The regex string to match again.
|
|
217
|
+
:return: An iterable of file paths that match the given regex.
|
|
218
|
+
"""
|
|
219
|
+
return self._wrapper.all_files_match(match)
|
|
220
|
+
|
|
221
|
+
def has_file(self, relative_path: str) -> bool:
|
|
222
|
+
"""
|
|
223
|
+
Does the requested file exist.
|
|
224
|
+
|
|
225
|
+
:param relative_path:
|
|
226
|
+
:return:
|
|
227
|
+
"""
|
|
228
|
+
return self._wrapper.has_file(relative_path)
|
|
229
|
+
|
|
230
|
+
def open(self, relative_path: str) -> Readable:
|
|
231
|
+
"""
|
|
232
|
+
Get the contents of the file.
|
|
233
|
+
|
|
234
|
+
:param relative_path:
|
|
235
|
+
:return:
|
|
236
|
+
"""
|
|
237
|
+
return self._wrapper.open(relative_path)
|
|
238
|
+
|
|
239
|
+
def close(self) -> None:
|
|
240
|
+
"""Close the contents."""
|
|
241
|
+
self._wrapper.close()
|
|
@@ -0,0 +1,197 @@
|
|
|
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: ...
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from typing import Iterable
|
|
2
|
+
from .data_pack import DataPack, Readable
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class DataPackManager:
|
|
6
|
+
"""
|
|
7
|
+
The DataPackManager class contains one or more data packs.
|
|
8
|
+
It manages loading them so that the stacking order is maintained.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
def __init__(self, data_packs: Iterable[DataPack]):
|
|
12
|
+
"""
|
|
13
|
+
Construct a new DataPackManager class.
|
|
14
|
+
|
|
15
|
+
:param data_packs: The data packs to load from. Later in the list get higher priority.
|
|
16
|
+
"""
|
|
17
|
+
self._data_packs = tuple(
|
|
18
|
+
reversed(
|
|
19
|
+
tuple(
|
|
20
|
+
pack
|
|
21
|
+
for pack in data_packs
|
|
22
|
+
if isinstance(pack, DataPack) and pack.is_valid
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def all_files(self) -> Iterable[str]:
|
|
29
|
+
"""
|
|
30
|
+
The relative paths of all files contained within.
|
|
31
|
+
|
|
32
|
+
:return: An iterable of paths.
|
|
33
|
+
"""
|
|
34
|
+
all_files: set[str] = set()
|
|
35
|
+
for pack in self._data_packs:
|
|
36
|
+
all_files.update(pack.all_files)
|
|
37
|
+
return all_files
|
|
38
|
+
|
|
39
|
+
def all_files_match(self, match: str) -> Iterable[str]:
|
|
40
|
+
"""
|
|
41
|
+
The relative paths of all files contained within that match the given regex.
|
|
42
|
+
|
|
43
|
+
:param match: The regex string to match again.
|
|
44
|
+
:return: An iterable of file paths that match the given regex.
|
|
45
|
+
"""
|
|
46
|
+
all_files: set[str] = set()
|
|
47
|
+
for pack in self._data_packs:
|
|
48
|
+
all_files.update(pack.all_files_match(match))
|
|
49
|
+
return all_files
|
|
50
|
+
|
|
51
|
+
def has_file(self, relative_path: str) -> bool:
|
|
52
|
+
"""
|
|
53
|
+
Does the requested file exist.
|
|
54
|
+
|
|
55
|
+
:param relative_path:
|
|
56
|
+
:return:
|
|
57
|
+
"""
|
|
58
|
+
return any(pack.has_file(relative_path) for pack in self._data_packs)
|
|
59
|
+
|
|
60
|
+
def open(self, relative_path: str) -> Readable:
|
|
61
|
+
"""
|
|
62
|
+
Get the contents of the file.
|
|
63
|
+
|
|
64
|
+
:param relative_path:
|
|
65
|
+
:return:
|
|
66
|
+
"""
|
|
67
|
+
for pack in self._data_packs:
|
|
68
|
+
if pack.has_file(relative_path):
|
|
69
|
+
return pack.open(relative_path)
|
|
70
|
+
raise FileNotFoundError(
|
|
71
|
+
f"The requested path {relative_path} could not be found."
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def close(self) -> None:
|
|
75
|
+
"""Close the contents."""
|
|
76
|
+
for pack in self._data_packs:
|
|
77
|
+
pack.close()
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import amulet.level.java._raw._data_pack.data_pack
|
|
4
|
+
from amulet.level.java._raw._data_pack.data_pack import DataPack, Readable
|
|
5
|
+
|
|
6
|
+
__all__ = ["DataPack", "DataPackManager", "Readable"]
|
|
7
|
+
|
|
8
|
+
class DataPackManager:
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
The DataPackManager class contains one or more data packs.
|
|
12
|
+
It manages loading them so that the stacking order is maintained.
|
|
13
|
+
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(
|
|
17
|
+
self,
|
|
18
|
+
data_packs: typing.Iterable[
|
|
19
|
+
amulet.level.java._raw._data_pack.data_pack.DataPack
|
|
20
|
+
],
|
|
21
|
+
):
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
Construct a new DataPackManager class.
|
|
25
|
+
|
|
26
|
+
:param data_packs: The data packs to load from. Later in the list get higher priority.
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def all_files_match(self, match: str) -> typing.Iterable[str]:
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
The relative paths of all files contained within that match the given regex.
|
|
34
|
+
|
|
35
|
+
:param match: The regex string to match again.
|
|
36
|
+
:return: An iterable of file paths that match the given regex.
|
|
37
|
+
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def close(self) -> None:
|
|
41
|
+
"""
|
|
42
|
+
Close the contents.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
def has_file(self, relative_path: str) -> bool:
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
Does the requested file exist.
|
|
49
|
+
|
|
50
|
+
:param relative_path:
|
|
51
|
+
:return:
|
|
52
|
+
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def open(
|
|
56
|
+
self, relative_path: str
|
|
57
|
+
) -> amulet.level.java._raw._data_pack.data_pack.Readable:
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
Get the contents of the file.
|
|
61
|
+
|
|
62
|
+
:param relative_path:
|
|
63
|
+
:return:
|
|
64
|
+
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def all_files(self) -> typing.Iterable[str]:
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
The relative paths of all files contained within.
|
|
72
|
+
|
|
73
|
+
:return: An iterable of paths.
|
|
74
|
+
|
|
75
|
+
"""
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from typing import Iterable, TYPE_CHECKING, Callable
|
|
3
|
+
|
|
4
|
+
from amulet.biome import Biome
|
|
5
|
+
from amulet.block import BlockStack
|
|
6
|
+
from amulet.data_types import DimensionId, ChunkCoordinates
|
|
7
|
+
from amulet.level.abc import RawDimension, RawLevelFriend
|
|
8
|
+
from amulet.selection import SelectionGroup
|
|
9
|
+
|
|
10
|
+
from amulet.level.java.anvil import RawChunkType, AnvilDimension
|
|
11
|
+
from amulet.level.java.chunk import JavaChunk
|
|
12
|
+
from ._typing import InternalDimensionId
|
|
13
|
+
|
|
14
|
+
from ._chunk import decode_chunk, encode_chunk
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from ._level import JavaRawLevel
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class JavaRawDimension(
|
|
22
|
+
RawLevelFriend["JavaRawLevel"], RawDimension[RawChunkType, JavaChunk]
|
|
23
|
+
):
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
raw_level_ref: Callable[[], JavaRawLevel | None],
|
|
27
|
+
anvil_dimension: AnvilDimension,
|
|
28
|
+
relative_path: InternalDimensionId,
|
|
29
|
+
dimension_id: DimensionId,
|
|
30
|
+
bounds: SelectionGroup,
|
|
31
|
+
default_block: BlockStack,
|
|
32
|
+
default_biome: Biome,
|
|
33
|
+
) -> None:
|
|
34
|
+
super().__init__(raw_level_ref)
|
|
35
|
+
self._anvil_dimension = anvil_dimension
|
|
36
|
+
self._relative_path = relative_path
|
|
37
|
+
self._dimension_id = dimension_id
|
|
38
|
+
self._bounds = bounds
|
|
39
|
+
self._default_block = default_block
|
|
40
|
+
self._default_biome = default_biome
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def dimension_id(self) -> DimensionId:
|
|
44
|
+
return self._dimension_id
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def relative_path(self) -> InternalDimensionId:
|
|
48
|
+
return self._relative_path
|
|
49
|
+
|
|
50
|
+
def bounds(self) -> SelectionGroup:
|
|
51
|
+
return self._bounds
|
|
52
|
+
|
|
53
|
+
def default_block(self) -> BlockStack:
|
|
54
|
+
return self._default_block
|
|
55
|
+
|
|
56
|
+
def default_biome(self) -> Biome:
|
|
57
|
+
return self._default_biome
|
|
58
|
+
|
|
59
|
+
def all_chunk_coords(self) -> Iterable[ChunkCoordinates]:
|
|
60
|
+
yield from self._anvil_dimension.all_chunk_coords()
|
|
61
|
+
|
|
62
|
+
def has_chunk(self, cx: int, cz: int) -> bool:
|
|
63
|
+
return self._anvil_dimension.has_chunk(cx, cz)
|
|
64
|
+
|
|
65
|
+
def delete_chunk(self, cx: int, cz: int) -> None:
|
|
66
|
+
self._anvil_dimension.delete_chunk(cx, cz)
|
|
67
|
+
|
|
68
|
+
def get_raw_chunk(self, cx: int, cz: int) -> RawChunkType:
|
|
69
|
+
return self._anvil_dimension.get_chunk_data(cx, cz)
|
|
70
|
+
|
|
71
|
+
def set_raw_chunk(self, cx: int, cz: int, chunk: RawChunkType) -> None:
|
|
72
|
+
self._anvil_dimension.put_chunk_data(cx, cz, chunk)
|
|
73
|
+
|
|
74
|
+
def raw_chunk_to_native_chunk(
|
|
75
|
+
self, raw_chunk: RawChunkType, cx: int, cz: int
|
|
76
|
+
) -> JavaChunk:
|
|
77
|
+
return decode_chunk(self._r, self, raw_chunk, cx, cz)
|
|
78
|
+
|
|
79
|
+
def native_chunk_to_raw_chunk(
|
|
80
|
+
self, chunk: JavaChunk, cx: int, cz: int
|
|
81
|
+
) -> RawChunkType:
|
|
82
|
+
return encode_chunk(self._r, self, chunk, cx, cz)
|
|
83
|
+
|
|
84
|
+
def compact(self) -> None:
|
|
85
|
+
"""Compact all region files"""
|
|
86
|
+
self._anvil_dimension.compact()
|