amulet-core 2.0a5__cp311-cp311-macosx_10_9_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.

Files changed (210) hide show
  1. amulet/__init__.cpython-311-darwin.so +0 -0
  2. amulet/__init__.pyi +30 -0
  3. amulet/__pyinstaller/__init__.py +2 -0
  4. amulet/__pyinstaller/hook-amulet.py +4 -0
  5. amulet/_init.py +28 -0
  6. amulet/_version.py +21 -0
  7. amulet/biome.cpp +36 -0
  8. amulet/biome.hpp +43 -0
  9. amulet/biome.pyi +77 -0
  10. amulet/block.cpp +435 -0
  11. amulet/block.hpp +119 -0
  12. amulet/block.pyi +273 -0
  13. amulet/block_entity.cpp +12 -0
  14. amulet/block_entity.hpp +56 -0
  15. amulet/block_entity.pyi +80 -0
  16. amulet/chunk.cpp +16 -0
  17. amulet/chunk.hpp +99 -0
  18. amulet/chunk.pyi +30 -0
  19. amulet/chunk_/components/biome.py +155 -0
  20. amulet/chunk_/components/block_entity.py +117 -0
  21. amulet/chunk_/components/entity.py +64 -0
  22. amulet/chunk_/components/height_2d.py +16 -0
  23. amulet/chunk_components.pyi +95 -0
  24. amulet/collections.pyi +37 -0
  25. amulet/data_types.py +29 -0
  26. amulet/entity.py +180 -0
  27. amulet/errors.py +63 -0
  28. amulet/game/__init__.py +7 -0
  29. amulet/game/_game.py +152 -0
  30. amulet/game/_universal/__init__.py +1 -0
  31. amulet/game/_universal/_biome.py +17 -0
  32. amulet/game/_universal/_block.py +47 -0
  33. amulet/game/_universal/_version.py +68 -0
  34. amulet/game/abc/__init__.py +22 -0
  35. amulet/game/abc/_block_specification.py +150 -0
  36. amulet/game/abc/biome.py +213 -0
  37. amulet/game/abc/block.py +331 -0
  38. amulet/game/abc/game_version_container.py +25 -0
  39. amulet/game/abc/json_interface.py +27 -0
  40. amulet/game/abc/version.py +44 -0
  41. amulet/game/bedrock/__init__.py +1 -0
  42. amulet/game/bedrock/_biome.py +35 -0
  43. amulet/game/bedrock/_block.py +42 -0
  44. amulet/game/bedrock/_version.py +165 -0
  45. amulet/game/java/__init__.py +2 -0
  46. amulet/game/java/_biome.py +35 -0
  47. amulet/game/java/_block.py +60 -0
  48. amulet/game/java/_version.py +176 -0
  49. amulet/game/translate/__init__.py +12 -0
  50. amulet/game/translate/_functions/__init__.py +15 -0
  51. amulet/game/translate/_functions/_code_functions/__init__.py +0 -0
  52. amulet/game/translate/_functions/_code_functions/_text.py +553 -0
  53. amulet/game/translate/_functions/_code_functions/banner_pattern.py +67 -0
  54. amulet/game/translate/_functions/_code_functions/bedrock_chest_connection.py +152 -0
  55. amulet/game/translate/_functions/_code_functions/bedrock_moving_block_pos.py +88 -0
  56. amulet/game/translate/_functions/_code_functions/bedrock_sign.py +152 -0
  57. amulet/game/translate/_functions/_code_functions/bedrock_skull_rotation.py +16 -0
  58. amulet/game/translate/_functions/_code_functions/custom_name.py +146 -0
  59. amulet/game/translate/_functions/_frozen.py +66 -0
  60. amulet/game/translate/_functions/_state.py +54 -0
  61. amulet/game/translate/_functions/_typing.py +98 -0
  62. amulet/game/translate/_functions/abc.py +116 -0
  63. amulet/game/translate/_functions/carry_nbt.py +160 -0
  64. amulet/game/translate/_functions/carry_properties.py +80 -0
  65. amulet/game/translate/_functions/code.py +143 -0
  66. amulet/game/translate/_functions/map_block_name.py +66 -0
  67. amulet/game/translate/_functions/map_nbt.py +111 -0
  68. amulet/game/translate/_functions/map_properties.py +93 -0
  69. amulet/game/translate/_functions/multiblock.py +112 -0
  70. amulet/game/translate/_functions/new_block.py +42 -0
  71. amulet/game/translate/_functions/new_entity.py +43 -0
  72. amulet/game/translate/_functions/new_nbt.py +206 -0
  73. amulet/game/translate/_functions/new_properties.py +64 -0
  74. amulet/game/translate/_functions/sequence.py +51 -0
  75. amulet/game/translate/_functions/walk_input_nbt.py +331 -0
  76. amulet/game/translate/_translator.py +433 -0
  77. amulet/item.py +75 -0
  78. amulet/level/__init__.pyi +27 -0
  79. amulet/level/_load.py +100 -0
  80. amulet/level/abc/__init__.py +12 -0
  81. amulet/level/abc/_chunk_handle.py +335 -0
  82. amulet/level/abc/_dimension.py +86 -0
  83. amulet/level/abc/_history/__init__.py +1 -0
  84. amulet/level/abc/_history/_cache.py +224 -0
  85. amulet/level/abc/_history/_history_manager.py +291 -0
  86. amulet/level/abc/_level/__init__.py +5 -0
  87. amulet/level/abc/_level/_compactable_level.py +10 -0
  88. amulet/level/abc/_level/_creatable_level.py +29 -0
  89. amulet/level/abc/_level/_disk_level.py +17 -0
  90. amulet/level/abc/_level/_level.py +453 -0
  91. amulet/level/abc/_level/_loadable_level.py +42 -0
  92. amulet/level/abc/_player_storage.py +7 -0
  93. amulet/level/abc/_raw_level.py +187 -0
  94. amulet/level/abc/_registry.py +40 -0
  95. amulet/level/bedrock/__init__.py +2 -0
  96. amulet/level/bedrock/_chunk_handle.py +19 -0
  97. amulet/level/bedrock/_dimension.py +22 -0
  98. amulet/level/bedrock/_level.py +187 -0
  99. amulet/level/bedrock/_raw/__init__.py +5 -0
  100. amulet/level/bedrock/_raw/_actor_counter.py +53 -0
  101. amulet/level/bedrock/_raw/_chunk.py +54 -0
  102. amulet/level/bedrock/_raw/_chunk_decode.py +668 -0
  103. amulet/level/bedrock/_raw/_chunk_encode.py +602 -0
  104. amulet/level/bedrock/_raw/_constant.py +9 -0
  105. amulet/level/bedrock/_raw/_dimension.py +343 -0
  106. amulet/level/bedrock/_raw/_level.py +463 -0
  107. amulet/level/bedrock/_raw/_level_dat.py +90 -0
  108. amulet/level/bedrock/_raw/_typing.py +6 -0
  109. amulet/level/bedrock/_raw/leveldb_chunk_versions.py +83 -0
  110. amulet/level/bedrock/chunk/__init__.py +1 -0
  111. amulet/level/bedrock/chunk/_chunk.py +126 -0
  112. amulet/level/bedrock/chunk/components/__init__.py +0 -0
  113. amulet/level/bedrock/chunk/components/chunk_version.py +12 -0
  114. amulet/level/bedrock/chunk/components/finalised_state.py +13 -0
  115. amulet/level/bedrock/chunk/components/raw_chunk.py +15 -0
  116. amulet/level/construction/__init__.py +0 -0
  117. amulet/level/java/__init__.pyi +21 -0
  118. amulet/level/java/_chunk_handle.py +17 -0
  119. amulet/level/java/_chunk_handle.pyi +15 -0
  120. amulet/level/java/_dimension.py +20 -0
  121. amulet/level/java/_dimension.pyi +13 -0
  122. amulet/level/java/_level.py +184 -0
  123. amulet/level/java/_level.pyi +120 -0
  124. amulet/level/java/_raw/__init__.pyi +19 -0
  125. amulet/level/java/_raw/_chunk.pyi +23 -0
  126. amulet/level/java/_raw/_chunk_decode.py +561 -0
  127. amulet/level/java/_raw/_chunk_encode.py +463 -0
  128. amulet/level/java/_raw/_constant.py +9 -0
  129. amulet/level/java/_raw/_constant.pyi +20 -0
  130. amulet/level/java/_raw/_data_pack/__init__.py +2 -0
  131. amulet/level/java/_raw/_data_pack/__init__.pyi +8 -0
  132. amulet/level/java/_raw/_data_pack/data_pack.py +241 -0
  133. amulet/level/java/_raw/_data_pack/data_pack.pyi +197 -0
  134. amulet/level/java/_raw/_data_pack/data_pack_manager.py +77 -0
  135. amulet/level/java/_raw/_data_pack/data_pack_manager.pyi +75 -0
  136. amulet/level/java/_raw/_dimension.py +86 -0
  137. amulet/level/java/_raw/_dimension.pyi +72 -0
  138. amulet/level/java/_raw/_level.py +507 -0
  139. amulet/level/java/_raw/_level.pyi +238 -0
  140. amulet/level/java/_raw/_typing.py +3 -0
  141. amulet/level/java/_raw/_typing.pyi +5 -0
  142. amulet/level/java/anvil/__init__.py +2 -0
  143. amulet/level/java/anvil/__init__.pyi +11 -0
  144. amulet/level/java/anvil/_dimension.py +170 -0
  145. amulet/level/java/anvil/_dimension.pyi +109 -0
  146. amulet/level/java/anvil/_region.py +421 -0
  147. amulet/level/java/anvil/_region.pyi +197 -0
  148. amulet/level/java/anvil/_sector_manager.py +223 -0
  149. amulet/level/java/anvil/_sector_manager.pyi +142 -0
  150. amulet/level/java/chunk.pyi +81 -0
  151. amulet/level/java/chunk_/_chunk.py +260 -0
  152. amulet/level/java/chunk_/components/inhabited_time.py +12 -0
  153. amulet/level/java/chunk_/components/last_update.py +12 -0
  154. amulet/level/java/chunk_/components/legacy_version.py +12 -0
  155. amulet/level/java/chunk_/components/light_populated.py +12 -0
  156. amulet/level/java/chunk_/components/named_height_2d.py +37 -0
  157. amulet/level/java/chunk_/components/status.py +11 -0
  158. amulet/level/java/chunk_/components/terrain_populated.py +12 -0
  159. amulet/level/java/chunk_components.pyi +22 -0
  160. amulet/level/java/long_array.pyi +38 -0
  161. amulet/level/java_forge/__init__.py +0 -0
  162. amulet/level/mcstructure/__init__.py +0 -0
  163. amulet/level/nbt/__init__.py +0 -0
  164. amulet/level/schematic/__init__.py +0 -0
  165. amulet/level/sponge_schematic/__init__.py +0 -0
  166. amulet/level/temporary_level/__init__.py +1 -0
  167. amulet/level/temporary_level/_level.py +16 -0
  168. amulet/palette/__init__.pyi +8 -0
  169. amulet/palette/biome_palette.pyi +45 -0
  170. amulet/palette/block_palette.pyi +45 -0
  171. amulet/player.py +64 -0
  172. amulet/py.typed +0 -0
  173. amulet/selection/__init__.py +2 -0
  174. amulet/selection/abstract_selection.py +342 -0
  175. amulet/selection/box.py +852 -0
  176. amulet/selection/group.py +481 -0
  177. amulet/utils/__init__.pyi +28 -0
  178. amulet/utils/call_spec/__init__.py +24 -0
  179. amulet/utils/call_spec/__init__.pyi +53 -0
  180. amulet/utils/call_spec/_call_spec.py +262 -0
  181. amulet/utils/call_spec/_call_spec.pyi +272 -0
  182. amulet/utils/format_utils.py +41 -0
  183. amulet/utils/generator.py +18 -0
  184. amulet/utils/matrix.py +243 -0
  185. amulet/utils/matrix.pyi +177 -0
  186. amulet/utils/numpy.pyi +11 -0
  187. amulet/utils/numpy_helpers.py +19 -0
  188. amulet/utils/shareable_lock.py +335 -0
  189. amulet/utils/shareable_lock.pyi +190 -0
  190. amulet/utils/signal/__init__.py +10 -0
  191. amulet/utils/signal/__init__.pyi +25 -0
  192. amulet/utils/signal/_signal.py +228 -0
  193. amulet/utils/signal/_signal.pyi +84 -0
  194. amulet/utils/task_manager.py +235 -0
  195. amulet/utils/task_manager.pyi +168 -0
  196. amulet/utils/typed_property.py +111 -0
  197. amulet/utils/typing.py +4 -0
  198. amulet/utils/typing.pyi +6 -0
  199. amulet/utils/weakref.py +70 -0
  200. amulet/utils/weakref.pyi +50 -0
  201. amulet/utils/world_utils.py +102 -0
  202. amulet/utils/world_utils.pyi +109 -0
  203. amulet/version.cpp +136 -0
  204. amulet/version.hpp +142 -0
  205. amulet/version.pyi +94 -0
  206. amulet_core-2.0a5.dist-info/METADATA +103 -0
  207. amulet_core-2.0a5.dist-info/RECORD +210 -0
  208. amulet_core-2.0a5.dist-info/WHEEL +5 -0
  209. amulet_core-2.0a5.dist-info/entry_points.txt +2 -0
  210. amulet_core-2.0a5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,238 @@
1
+ from __future__ import annotations
2
+
3
+ import copy as copy
4
+ import glob as glob
5
+ import json as json
6
+ import logging as logging
7
+ import os as os
8
+ import shutil as shutil
9
+ import struct as struct
10
+ import time as time
11
+ import typing
12
+ from builtins import str as DimensionId
13
+ from builtins import str as InternalDimensionId
14
+ from dataclasses import dataclass
15
+ from threading import RLock
16
+ from typing import BinaryIO
17
+
18
+ import amulet.level.abc._raw_level
19
+ import amulet.selection.group
20
+ import portalocker as portalocker
21
+ from amulet.biome import Biome
22
+ from amulet.block import Block, BlockStack
23
+ from amulet.errors import LevelWriteError
24
+ from amulet.game._game import get_game_version
25
+ from amulet.level.abc._raw_level import RawLevel
26
+ from amulet.level.abc._registry import IdRegistry
27
+ from amulet.level.java._raw._data_pack.data_pack import DataPack
28
+ from amulet.level.java._raw._data_pack.data_pack_manager import DataPackManager
29
+ from amulet.level.java._raw._dimension import JavaRawDimension
30
+ from amulet.level.java.anvil._dimension import AnvilDimension
31
+ from amulet.selection.box import SelectionBox
32
+ from amulet.selection.group import SelectionGroup
33
+ from amulet.utils.signal._signal import Signal
34
+ from amulet.utils.weakref import DetachableWeakRef
35
+ from amulet.version import VersionNumber
36
+ from amulet_nbt import (
37
+ CompoundTag,
38
+ IntTag,
39
+ ListTag,
40
+ LongTag,
41
+ NamedTag,
42
+ StringTag,
43
+ read_nbt,
44
+ )
45
+
46
+ __all__ = [
47
+ "AnvilDimension",
48
+ "BinaryIO",
49
+ "Biome",
50
+ "Block",
51
+ "BlockStack",
52
+ "CompoundTag",
53
+ "DataPack",
54
+ "DataPackManager",
55
+ "DefaultSelection",
56
+ "DetachableWeakRef",
57
+ "DimensionId",
58
+ "IdRegistry",
59
+ "IntTag",
60
+ "InternalDimensionId",
61
+ "JavaCreateArgsV1",
62
+ "JavaRawDimension",
63
+ "JavaRawLevel",
64
+ "JavaRawLevelOpenData",
65
+ "LevelWriteError",
66
+ "ListTag",
67
+ "LongTag",
68
+ "NamedTag",
69
+ "OVERWORLD",
70
+ "RLock",
71
+ "RawLevel",
72
+ "SelectionBox",
73
+ "SelectionGroup",
74
+ "Signal",
75
+ "SignalInstanceCacheName",
76
+ "StringTag",
77
+ "THE_END",
78
+ "THE_NETHER",
79
+ "VersionNumber",
80
+ "copy",
81
+ "dataclass",
82
+ "get_game_version",
83
+ "glob",
84
+ "json",
85
+ "log",
86
+ "logging",
87
+ "os",
88
+ "portalocker",
89
+ "read_nbt",
90
+ "shutil",
91
+ "struct",
92
+ "time",
93
+ ]
94
+
95
+ class JavaCreateArgsV1:
96
+ """
97
+ A class to house call arguments to create.
98
+
99
+ If the call arguments to create need to be modified in the future a new arguments class can be created.
100
+ The create method can inspect which class it was given and access arguments accordingly.
101
+
102
+ """
103
+
104
+ __hash__: typing.ClassVar[None] = None
105
+ def __eq__(self, other): ...
106
+ def __init__(
107
+ self, overwrite: bool, path: str, version: VersionNumber, level_name: str
108
+ ) -> None: ...
109
+ def __repr__(self): ...
110
+
111
+ class JavaRawLevel(amulet.level.abc._raw_level.RawLevel):
112
+ __slots__: typing.ClassVar[tuple] = (
113
+ "_path",
114
+ "_level_dat",
115
+ "_data_version",
116
+ "_raw_open_data",
117
+ "_SignalCache",
118
+ )
119
+ level_name: str
120
+ @staticmethod
121
+ def closed(*args, **kwargs): ...
122
+ @staticmethod
123
+ def opened(*args, **kwargs): ...
124
+ @classmethod
125
+ def create(cls, args: JavaCreateArgsV1) -> JavaRawLevel: ...
126
+ @classmethod
127
+ def load(cls, path: str) -> JavaRawLevel: ...
128
+ def __init__(self, _ikwiad: bool = False) -> None: ...
129
+ def _find_dimensions(self) -> None: ...
130
+ def _get_dimension_bounds(
131
+ self, dimension_type_str: DimensionId
132
+ ) -> SelectionGroup: ...
133
+ def _register_dimension(
134
+ self, relative_dimension_path: InternalDimensionId, dimension_name: DimensionId
135
+ ) -> None:
136
+ """
137
+
138
+ Register a new dimension.
139
+
140
+ :param relative_dimension_path: The relative path to the dimension directory from the world root.
141
+ "" for the world root.
142
+ :param dimension_name: The name of the dimension shown to the user
143
+
144
+ """
145
+
146
+ def _update_data_version(self) -> None:
147
+ """
148
+ Pull the data version from the level.dat file
149
+ """
150
+
151
+ def close(self) -> None:
152
+ """
153
+ Close the raw level.
154
+ """
155
+
156
+ def compact(self) -> None:
157
+ """
158
+ Compact all region files
159
+ """
160
+
161
+ def dimension_ids(self) -> frozenset[DimensionId]: ...
162
+ def get_dimension(self, dimension_id: DimensionId) -> JavaRawDimension: ...
163
+ def is_open(self) -> bool: ...
164
+ def open(self) -> None:
165
+ """
166
+ Open the raw level.
167
+ """
168
+
169
+ def reload(self) -> None:
170
+ """
171
+ Reload the raw level.
172
+ """
173
+
174
+ @property
175
+ def _o(self) -> JavaRawLevelOpenData: ...
176
+ @property
177
+ def biome_id_override(self) -> IdRegistry:
178
+ """
179
+
180
+ A two-way map from hard coded numerical biome id <-> biome string.
181
+ This only stores overridden values. If the value is not present here you should check the translator.
182
+
183
+ """
184
+
185
+ @property
186
+ def block_id_override(self) -> IdRegistry:
187
+ """
188
+
189
+ A two-way map from hard coded numerical block id <-> block string.
190
+ This only stores overridden values. If the value is not present here you should check the translator.
191
+
192
+ """
193
+
194
+ @property
195
+ def data_version(self) -> VersionNumber:
196
+ """
197
+
198
+ The game data version that the level was last opened in.
199
+ This is used to determine the data format to save in.
200
+
201
+ """
202
+
203
+ @property
204
+ def level_dat(self) -> NamedTag:
205
+ """
206
+ Get the level.dat file for the world
207
+ """
208
+
209
+ @level_dat.setter
210
+ def level_dat(self, level_dat: NamedTag) -> None: ...
211
+ @property
212
+ def modified_time(self) -> float:
213
+ """
214
+ Unix timestamp of when the level was last modified.
215
+ """
216
+
217
+ @property
218
+ def path(self) -> str: ...
219
+ @property
220
+ def platform(self) -> str: ...
221
+
222
+ class JavaRawLevelOpenData:
223
+ def __init__(
224
+ self,
225
+ raw_level: JavaRawLevel,
226
+ lock_file: BinaryIO,
227
+ lock_time: float,
228
+ data_pack: DataPackManager,
229
+ ) -> None: ...
230
+
231
+ DefaultSelection: (
232
+ amulet.selection.group.SelectionGroup
233
+ ) # value = SelectionGroup([SelectionBox((-30000000, 0, -30000000), (30000000, 256, 30000000))])
234
+ OVERWORLD: str
235
+ SignalInstanceCacheName: str
236
+ THE_END: str
237
+ THE_NETHER: str
238
+ log: logging.Logger # value = <Logger amulet.level.java._raw._level (INFO)>
@@ -0,0 +1,3 @@
1
+ from typing import TypeAlias
2
+
3
+ InternalDimensionId: TypeAlias = str
@@ -0,0 +1,5 @@
1
+ from __future__ import annotations
2
+
3
+ from builtins import str as InternalDimensionId
4
+
5
+ __all__ = ["InternalDimensionId"]
@@ -0,0 +1,2 @@
1
+ from ._region import AnvilRegion
2
+ from ._dimension import AnvilDimension, AnvilDimensionLayer, RawChunkType
@@ -0,0 +1,11 @@
1
+ from __future__ import annotations
2
+
3
+ import types
4
+
5
+ from amulet.level.java.anvil._dimension import AnvilDimension, AnvilDimensionLayer
6
+ from amulet.level.java.anvil._region import AnvilRegion
7
+
8
+ from . import _dimension, _region, _sector_manager
9
+
10
+ __all__ = ["AnvilDimension", "AnvilDimensionLayer", "AnvilRegion", "RawChunkType"]
11
+ RawChunkType: types.GenericAlias # value = dict[str, amulet_nbt.NamedTag]
@@ -0,0 +1,170 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TypeAlias
4
+ import os
5
+ from collections.abc import Iterator, Sequence
6
+ import re
7
+ import threading
8
+
9
+ from amulet_nbt import NamedTag
10
+
11
+ from amulet.utils import world_utils
12
+ from amulet.errors import ChunkDoesNotExist
13
+ from amulet.data_types import (
14
+ ChunkCoordinates,
15
+ RegionCoordinates,
16
+ )
17
+ from ._region import AnvilRegion
18
+
19
+
20
+ RawChunkType: TypeAlias = dict[str, NamedTag]
21
+
22
+
23
+ class AnvilDimensionLayer:
24
+ """A class to manage a directory of region files."""
25
+
26
+ def __init__(self, directory: str, *, mcc: bool = False):
27
+ self._directory = directory
28
+ self._regions: dict[RegionCoordinates, AnvilRegion] = {}
29
+ self._mcc = mcc
30
+ self._lock = threading.RLock()
31
+
32
+ def _region_path(self, rx: int, rz: int) -> str:
33
+ """Get the file path for a region file."""
34
+ return os.path.join(self._directory, f"r.{rx}.{rz}.mca")
35
+
36
+ def _has_region(self, rx: int, rz: int) -> bool:
37
+ """Does a region file exist."""
38
+ return os.path.isfile(self._region_path(rx, rz))
39
+
40
+ def _get_region(self, rx: int, rz: int, create: bool = False) -> AnvilRegion:
41
+ with self._lock:
42
+ if (rx, rz) in self._regions:
43
+ return self._regions[(rx, rz)]
44
+ elif create or self._has_region(rx, rz):
45
+ region = self._regions[(rx, rz)] = AnvilRegion(
46
+ self._region_path(rx, rz), mcc=self._mcc
47
+ )
48
+ return region
49
+ else:
50
+ raise ChunkDoesNotExist
51
+
52
+ def _iter_regions(self) -> Iterator[AnvilRegion]:
53
+ if os.path.isdir(self._directory):
54
+ for region_file_name in os.listdir(self._directory):
55
+ try:
56
+ rx, rz = AnvilRegion.get_coords(region_file_name)
57
+ except ValueError:
58
+ continue
59
+ else:
60
+ yield self._get_region(rx, rz)
61
+
62
+ def all_chunk_coords(self) -> Iterator[ChunkCoordinates]:
63
+ for region in self._iter_regions():
64
+ yield from region.all_coords()
65
+
66
+ def has_chunk(self, cx: int, cz: int) -> bool:
67
+ try:
68
+ region = self._get_region(
69
+ *world_utils.chunk_coords_to_region_coords(cx, cz)
70
+ )
71
+ except ChunkDoesNotExist:
72
+ return False
73
+ else:
74
+ return region.has_data(cx, cz)
75
+
76
+ def get_chunk_data(self, cx: int, cz: int) -> NamedTag:
77
+ """
78
+ Get a NamedTag of a chunk from the database.
79
+ Will raise ChunkDoesNotExist if the region or chunk does not exist
80
+ """
81
+ # get the region key
82
+ return self._get_region(
83
+ *world_utils.chunk_coords_to_region_coords(cx, cz)
84
+ ).get_data(cx, cz)
85
+
86
+ def put_chunk_data(self, cx: int, cz: int, data: NamedTag) -> None:
87
+ """pass data to the region file class"""
88
+ self._get_region(
89
+ *world_utils.chunk_coords_to_region_coords(cx, cz), create=True
90
+ ).set_data(cx, cz, data)
91
+
92
+ def delete_chunk(self, cx: int, cz: int) -> None:
93
+ try:
94
+ region = self._get_region(
95
+ *world_utils.chunk_coords_to_region_coords(cx, cz)
96
+ )
97
+ except ChunkDoesNotExist:
98
+ pass
99
+ else:
100
+ region.delete_data(cx, cz)
101
+
102
+ def compact(self) -> None:
103
+ """Compact all region files in this layer"""
104
+ for region in self._iter_regions():
105
+ region.compact()
106
+
107
+
108
+ class AnvilDimension:
109
+ """
110
+ A class to manage the data for a dimension.
111
+ This can consist of multiple layers. Eg the region layer which contains chunk data and the entities layer which contains entities.
112
+ """
113
+
114
+ level_regex = re.compile(r"DIM(?P<level>-?\d+)")
115
+
116
+ def __init__(
117
+ self, directory: str, *, mcc: bool = False, layers: Sequence[str] = ("region",)
118
+ ) -> None:
119
+ self._directory = directory
120
+ self._mcc = mcc
121
+ self.__layers: dict[str, AnvilDimensionLayer] = {
122
+ layer: AnvilDimensionLayer(
123
+ os.path.join(self._directory, layer), mcc=self._mcc
124
+ )
125
+ for layer in layers
126
+ }
127
+ self.__default_layer = self.__layers[layers[0]]
128
+
129
+ def all_chunk_coords(self) -> Iterator[ChunkCoordinates]:
130
+ yield from self.__default_layer.all_chunk_coords()
131
+
132
+ def has_chunk(self, cx: int, cz: int) -> bool:
133
+ return self.__default_layer.has_chunk(cx, cz)
134
+
135
+ def get_chunk_data(self, cx: int, cz: int) -> RawChunkType:
136
+ """Get the chunk data for each layer"""
137
+ chunk_data = {}
138
+ for layer_name, layer in self.__layers.items():
139
+ try:
140
+ chunk_data[layer_name] = layer.get_chunk_data(cx, cz)
141
+ except ChunkDoesNotExist:
142
+ pass
143
+
144
+ if chunk_data:
145
+ return chunk_data
146
+ else:
147
+ raise ChunkDoesNotExist
148
+
149
+ def put_chunk_data(self, cx: int, cz: int, data_layers: RawChunkType) -> None:
150
+ """Put one or more layers of data"""
151
+ for layer_name, data in data_layers.items():
152
+ if (
153
+ layer_name not in self.__layers
154
+ and layer_name.isalpha()
155
+ and layer_name.islower()
156
+ ):
157
+ self.__layers[layer_name] = AnvilDimensionLayer(
158
+ os.path.join(self._directory, layer_name), mcc=self._mcc
159
+ )
160
+ if layer_name in self.__layers:
161
+ self.__layers[layer_name].put_chunk_data(cx, cz, data)
162
+
163
+ def delete_chunk(self, cx: int, cz: int) -> None:
164
+ for layer in self.__layers.values():
165
+ layer.delete_chunk(cx, cz)
166
+
167
+ def compact(self) -> None:
168
+ """Compact all region files in this dimension"""
169
+ for layer in self.__layers.values():
170
+ layer.compact()
@@ -0,0 +1,109 @@
1
+ from __future__ import annotations
2
+
3
+ import os as os
4
+ import re as re
5
+ import threading as threading
6
+ import types
7
+ import typing
8
+ from collections.abc import Iterator, Sequence
9
+
10
+ from amulet.errors import ChunkDoesNotExist
11
+ from amulet.level.java.anvil._region import AnvilRegion
12
+ from amulet.utils import world_utils
13
+ from amulet_nbt import NamedTag
14
+
15
+ __all__ = [
16
+ "AnvilDimension",
17
+ "AnvilDimensionLayer",
18
+ "AnvilRegion",
19
+ "ChunkCoordinates",
20
+ "ChunkDoesNotExist",
21
+ "Iterator",
22
+ "NamedTag",
23
+ "RawChunkType",
24
+ "RegionCoordinates",
25
+ "Sequence",
26
+ "os",
27
+ "re",
28
+ "threading",
29
+ "world_utils",
30
+ ]
31
+
32
+ class AnvilDimension:
33
+ """
34
+
35
+ A class to manage the data for a dimension.
36
+ This can consist of multiple layers. Eg the region layer which contains chunk data and the entities layer which contains entities.
37
+
38
+ """
39
+
40
+ level_regex: typing.ClassVar[
41
+ re.Pattern
42
+ ] # value = re.compile('DIM(?P<level>-?\\d+)')
43
+ def __init__(
44
+ self,
45
+ directory: str,
46
+ *,
47
+ mcc: bool = False,
48
+ layers: typing.Sequence[str] = ("region"),
49
+ ) -> None: ...
50
+ def all_chunk_coords(self) -> typing.Iterator[ChunkCoordinates]: ...
51
+ def compact(self) -> None:
52
+ """
53
+ Compact all region files in this dimension
54
+ """
55
+
56
+ def delete_chunk(self, cx: int, cz: int) -> None: ...
57
+ def get_chunk_data(self, cx: int, cz: int) -> RawChunkType:
58
+ """
59
+ Get the chunk data for each layer
60
+ """
61
+
62
+ def has_chunk(self, cx: int, cz: int) -> bool: ...
63
+ def put_chunk_data(self, cx: int, cz: int, data_layers: RawChunkType) -> None:
64
+ """
65
+ Put one or more layers of data
66
+ """
67
+
68
+ class AnvilDimensionLayer:
69
+ """
70
+ A class to manage a directory of region files.
71
+ """
72
+
73
+ def __init__(self, directory: str, *, mcc: bool = False): ...
74
+ def _get_region(self, rx: int, rz: int, create: bool = False) -> AnvilRegion: ...
75
+ def _has_region(self, rx: int, rz: int) -> bool:
76
+ """
77
+ Does a region file exist.
78
+ """
79
+
80
+ def _iter_regions(self) -> typing.Iterator[AnvilRegion]: ...
81
+ def _region_path(self, rx: int, rz: int) -> str:
82
+ """
83
+ Get the file path for a region file.
84
+ """
85
+
86
+ def all_chunk_coords(self) -> typing.Iterator[ChunkCoordinates]: ...
87
+ def compact(self) -> None:
88
+ """
89
+ Compact all region files in this layer
90
+ """
91
+
92
+ def delete_chunk(self, cx: int, cz: int) -> None: ...
93
+ def get_chunk_data(self, cx: int, cz: int) -> NamedTag:
94
+ """
95
+
96
+ Get a NamedTag of a chunk from the database.
97
+ Will raise ChunkDoesNotExist if the region or chunk does not exist
98
+
99
+ """
100
+
101
+ def has_chunk(self, cx: int, cz: int) -> bool: ...
102
+ def put_chunk_data(self, cx: int, cz: int, data: NamedTag) -> None:
103
+ """
104
+ pass data to the region file class
105
+ """
106
+
107
+ ChunkCoordinates: types.GenericAlias # value = tuple[int, int]
108
+ RawChunkType: types.GenericAlias # value = dict[str, amulet_nbt.NamedTag]
109
+ RegionCoordinates: types.GenericAlias # value = tuple[int, int]