amulet-core 2.0a8__cp311-cp311-win_amd64.whl → 2.0.1a2.post250529084738__cp311-cp311-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.

Files changed (271) hide show
  1. amulet/core/__init__.py +36 -0
  2. amulet/core/__pyinstaller/hook-amulet.core.py +4 -0
  3. amulet/core/_amulet_core.cp311-win_amd64.pyd +0 -0
  4. amulet/core/_amulet_core.pyi +7 -0
  5. amulet/{_version.py → core/_version.py} +3 -3
  6. amulet/core/amulet_core.dll +0 -0
  7. amulet/core/amulet_core.lib +0 -0
  8. amulet/core/amulet_coreConfig.cmake +18 -0
  9. amulet/{biome.pyi → core/biome/__init__.pyi} +3 -3
  10. amulet/core/biome/biome.hpp +53 -0
  11. amulet/{block.pyi → core/block/__init__.pyi} +25 -26
  12. amulet/core/block/block.hpp +156 -0
  13. amulet/{block_entity.pyi → core/block_entity/__init__.pyi} +7 -7
  14. amulet/core/block_entity/block_entity.hpp +84 -0
  15. amulet/{errors.py → core/chunk/__init__.pyi} +37 -33
  16. amulet/core/chunk/chunk.hpp +126 -0
  17. amulet/core/chunk/component/__init__.pyi +18 -0
  18. amulet/core/chunk/component/biome_3d_component.hpp +96 -0
  19. amulet/core/chunk/component/block_component.hpp +101 -0
  20. amulet/core/chunk/component/block_component.pyi +28 -0
  21. amulet/core/chunk/component/block_entity_component.hpp +119 -0
  22. amulet/core/chunk/component/section_array_map.hpp +129 -0
  23. amulet/{chunk_components.pyi → core/chunk/component/section_array_map.pyi} +4 -24
  24. amulet/core/dll.hpp +21 -0
  25. amulet/core/entity/__init__.pyi +105 -0
  26. amulet/core/entity/entity.hpp +100 -0
  27. amulet/{palette → core/palette}/__init__.pyi +2 -2
  28. amulet/core/palette/biome_palette.hpp +65 -0
  29. amulet/{palette → core/palette}/biome_palette.pyi +8 -8
  30. amulet/core/palette/block_palette.hpp +71 -0
  31. amulet/{palette → core/palette}/block_palette.pyi +12 -10
  32. amulet/core/selection/__init__.pyi +8 -0
  33. amulet/core/selection/box.hpp +86 -0
  34. amulet/core/selection/box.pyi +215 -0
  35. amulet/core/selection/group.hpp +80 -0
  36. amulet/core/selection/group.pyi +213 -0
  37. amulet/{version.pyi → core/version/__init__.pyi} +58 -10
  38. amulet/core/version/version.hpp +204 -0
  39. {amulet_core-2.0a8.dist-info → amulet_core-2.0.1a2.post250529084738.dist-info}/METADATA +25 -20
  40. amulet_core-2.0.1a2.post250529084738.dist-info/RECORD +45 -0
  41. {amulet_core-2.0a8.dist-info → amulet_core-2.0.1a2.post250529084738.dist-info}/WHEEL +1 -1
  42. amulet_core-2.0.1a2.post250529084738.dist-info/entry_points.txt +2 -0
  43. amulet/__init__.cp311-win_amd64.pyd +0 -0
  44. amulet/__init__.py.cpp +0 -45
  45. amulet/__init__.pyi +0 -30
  46. amulet/__pyinstaller/hook-amulet.py +0 -4
  47. amulet/_init.py +0 -26
  48. amulet/biome.cpp +0 -36
  49. amulet/biome.hpp +0 -43
  50. amulet/biome.py.cpp +0 -122
  51. amulet/block.cpp +0 -435
  52. amulet/block.hpp +0 -119
  53. amulet/block.py.cpp +0 -377
  54. amulet/block_entity.cpp +0 -12
  55. amulet/block_entity.hpp +0 -56
  56. amulet/block_entity.py.cpp +0 -115
  57. amulet/chunk.cpp +0 -16
  58. amulet/chunk.hpp +0 -100
  59. amulet/chunk.py.cpp +0 -80
  60. amulet/chunk.pyi +0 -28
  61. amulet/chunk_components/biome_3d_component.cpp +0 -5
  62. amulet/chunk_components/biome_3d_component.hpp +0 -79
  63. amulet/chunk_components/block_component.cpp +0 -41
  64. amulet/chunk_components/block_component.hpp +0 -88
  65. amulet/chunk_components/block_entity_component.cpp +0 -5
  66. amulet/chunk_components/block_entity_component.hpp +0 -147
  67. amulet/chunk_components/section_array_map.cpp +0 -129
  68. amulet/chunk_components/section_array_map.hpp +0 -147
  69. amulet/collections/eq.py.hpp +0 -37
  70. amulet/collections/hash.py.hpp +0 -27
  71. amulet/collections/holder.py.hpp +0 -37
  72. amulet/collections/iterator.py.hpp +0 -80
  73. amulet/collections/mapping.py.hpp +0 -199
  74. amulet/collections/mutable_mapping.py.hpp +0 -226
  75. amulet/collections/sequence.py.hpp +0 -163
  76. amulet/collections.pyi +0 -40
  77. amulet/data_types.py +0 -29
  78. amulet/entity.py +0 -182
  79. amulet/game/__init__.py +0 -7
  80. amulet/game/_game.py +0 -152
  81. amulet/game/_universal/__init__.py +0 -1
  82. amulet/game/_universal/_biome.py +0 -17
  83. amulet/game/_universal/_block.py +0 -47
  84. amulet/game/_universal/_version.py +0 -68
  85. amulet/game/abc/__init__.py +0 -22
  86. amulet/game/abc/_block_specification.py +0 -150
  87. amulet/game/abc/biome.py +0 -213
  88. amulet/game/abc/block.py +0 -331
  89. amulet/game/abc/game_version_container.py +0 -25
  90. amulet/game/abc/json_interface.py +0 -27
  91. amulet/game/abc/version.py +0 -44
  92. amulet/game/bedrock/__init__.py +0 -1
  93. amulet/game/bedrock/_biome.py +0 -35
  94. amulet/game/bedrock/_block.py +0 -42
  95. amulet/game/bedrock/_version.py +0 -165
  96. amulet/game/java/__init__.py +0 -2
  97. amulet/game/java/_biome.py +0 -35
  98. amulet/game/java/_block.py +0 -60
  99. amulet/game/java/_version.py +0 -176
  100. amulet/game/translate/__init__.py +0 -12
  101. amulet/game/translate/_functions/__init__.py +0 -15
  102. amulet/game/translate/_functions/_code_functions/__init__.py +0 -0
  103. amulet/game/translate/_functions/_code_functions/_text.py +0 -553
  104. amulet/game/translate/_functions/_code_functions/banner_pattern.py +0 -67
  105. amulet/game/translate/_functions/_code_functions/bedrock_chest_connection.py +0 -152
  106. amulet/game/translate/_functions/_code_functions/bedrock_moving_block_pos.py +0 -88
  107. amulet/game/translate/_functions/_code_functions/bedrock_sign.py +0 -152
  108. amulet/game/translate/_functions/_code_functions/bedrock_skull_rotation.py +0 -16
  109. amulet/game/translate/_functions/_code_functions/custom_name.py +0 -146
  110. amulet/game/translate/_functions/_frozen.py +0 -66
  111. amulet/game/translate/_functions/_state.py +0 -54
  112. amulet/game/translate/_functions/_typing.py +0 -98
  113. amulet/game/translate/_functions/abc.py +0 -123
  114. amulet/game/translate/_functions/carry_nbt.py +0 -160
  115. amulet/game/translate/_functions/carry_properties.py +0 -80
  116. amulet/game/translate/_functions/code.py +0 -143
  117. amulet/game/translate/_functions/map_block_name.py +0 -66
  118. amulet/game/translate/_functions/map_nbt.py +0 -111
  119. amulet/game/translate/_functions/map_properties.py +0 -93
  120. amulet/game/translate/_functions/multiblock.py +0 -112
  121. amulet/game/translate/_functions/new_block.py +0 -42
  122. amulet/game/translate/_functions/new_entity.py +0 -43
  123. amulet/game/translate/_functions/new_nbt.py +0 -206
  124. amulet/game/translate/_functions/new_properties.py +0 -64
  125. amulet/game/translate/_functions/sequence.py +0 -51
  126. amulet/game/translate/_functions/walk_input_nbt.py +0 -331
  127. amulet/game/translate/_translator.py +0 -433
  128. amulet/img/__init__.py +0 -10
  129. amulet/img/missing_no.png +0 -0
  130. amulet/img/missing_pack.png +0 -0
  131. amulet/img/missing_world.png +0 -0
  132. amulet/io/binary_reader.hpp +0 -45
  133. amulet/io/binary_writer.hpp +0 -30
  134. amulet/item.py +0 -75
  135. amulet/level/__init__.pyi +0 -23
  136. amulet/level/_load.py +0 -100
  137. amulet/level/abc/__init__.py +0 -12
  138. amulet/level/abc/_chunk_handle.py +0 -358
  139. amulet/level/abc/_dimension.py +0 -86
  140. amulet/level/abc/_history/__init__.py +0 -1
  141. amulet/level/abc/_history/_cache.py +0 -224
  142. amulet/level/abc/_history/_history_manager.py +0 -291
  143. amulet/level/abc/_level/__init__.py +0 -5
  144. amulet/level/abc/_level/_compactable_level.py +0 -10
  145. amulet/level/abc/_level/_creatable_level.py +0 -28
  146. amulet/level/abc/_level/_disk_level.py +0 -17
  147. amulet/level/abc/_level/_level.py +0 -449
  148. amulet/level/abc/_level/_loadable_level.py +0 -42
  149. amulet/level/abc/_player_storage.py +0 -7
  150. amulet/level/abc/_raw_level.py +0 -187
  151. amulet/level/abc/_registry.py +0 -40
  152. amulet/level/java/__init__.pyi +0 -16
  153. amulet/level/java/_chunk_handle.py +0 -17
  154. amulet/level/java/_dimension.py +0 -20
  155. amulet/level/java/_level.py +0 -184
  156. amulet/level/java/_raw/__init__.pyi +0 -15
  157. amulet/level/java/_raw/_chunk.pyi +0 -23
  158. amulet/level/java/_raw/_constant.py +0 -9
  159. amulet/level/java/_raw/_data_pack/__init__.py +0 -2
  160. amulet/level/java/_raw/_data_pack/data_pack.py +0 -241
  161. amulet/level/java/_raw/_data_pack/data_pack_manager.py +0 -77
  162. amulet/level/java/_raw/_dimension.py +0 -86
  163. amulet/level/java/_raw/_level.py +0 -507
  164. amulet/level/java/_raw/_typing.py +0 -3
  165. amulet/level/java/_raw/java_chunk_decode.cpp +0 -531
  166. amulet/level/java/_raw/java_chunk_decode.hpp +0 -23
  167. amulet/level/java/_raw/java_chunk_encode.cpp +0 -25
  168. amulet/level/java/_raw/java_chunk_encode.hpp +0 -23
  169. amulet/level/java/anvil/__init__.py +0 -2
  170. amulet/level/java/anvil/_dimension.py +0 -170
  171. amulet/level/java/anvil/_region.py +0 -421
  172. amulet/level/java/anvil/_sector_manager.py +0 -223
  173. amulet/level/java/chunk.pyi +0 -81
  174. amulet/level/java/chunk_/_chunk.py +0 -260
  175. amulet/level/java/chunk_/components/inhabited_time.py +0 -12
  176. amulet/level/java/chunk_/components/last_update.py +0 -12
  177. amulet/level/java/chunk_/components/legacy_version.py +0 -12
  178. amulet/level/java/chunk_/components/light_populated.py +0 -12
  179. amulet/level/java/chunk_/components/named_height_2d.py +0 -37
  180. amulet/level/java/chunk_/components/status.py +0 -11
  181. amulet/level/java/chunk_/components/terrain_populated.py +0 -12
  182. amulet/level/java/chunk_components/data_version_component.cpp +0 -32
  183. amulet/level/java/chunk_components/data_version_component.hpp +0 -31
  184. amulet/level/java/chunk_components/java_raw_chunk_component.cpp +0 -56
  185. amulet/level/java/chunk_components/java_raw_chunk_component.hpp +0 -45
  186. amulet/level/java/chunk_components.pyi +0 -22
  187. amulet/level/java/java_chunk.cpp +0 -170
  188. amulet/level/java/java_chunk.hpp +0 -141
  189. amulet/level/java/long_array.hpp +0 -175
  190. amulet/level/java/long_array.pyi +0 -39
  191. amulet/level/temporary_level/__init__.py +0 -1
  192. amulet/level/temporary_level/_level.py +0 -16
  193. amulet/mesh/__init__.py +0 -0
  194. amulet/mesh/block/__init__.pyi +0 -301
  195. amulet/mesh/block/_cube.py +0 -198
  196. amulet/mesh/block/_missing_block.py +0 -20
  197. amulet/mesh/block/block_mesh.cpp +0 -107
  198. amulet/mesh/block/block_mesh.hpp +0 -207
  199. amulet/mesh/util.py +0 -17
  200. amulet/palette/biome_palette.hpp +0 -85
  201. amulet/palette/block_palette.cpp +0 -32
  202. amulet/palette/block_palette.hpp +0 -93
  203. amulet/player.py +0 -62
  204. amulet/pybind11/collections.hpp +0 -118
  205. amulet/pybind11/numpy.hpp +0 -26
  206. amulet/pybind11/py_module.hpp +0 -34
  207. amulet/pybind11/type_hints.hpp +0 -51
  208. amulet/pybind11/types.hpp +0 -25
  209. amulet/pybind11/typing.hpp +0 -7
  210. amulet/resource_pack/__init__.py +0 -63
  211. amulet/resource_pack/abc/__init__.py +0 -2
  212. amulet/resource_pack/abc/resource_pack.py +0 -38
  213. amulet/resource_pack/abc/resource_pack_manager.py +0 -85
  214. amulet/resource_pack/java/__init__.py +0 -2
  215. amulet/resource_pack/java/download_resources.py +0 -212
  216. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_black.png +0 -0
  217. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_blue.png +0 -0
  218. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_brown.png +0 -0
  219. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_cyan.png +0 -0
  220. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_gray.png +0 -0
  221. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_green.png +0 -0
  222. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_blue.png +0 -0
  223. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_gray.png +0 -0
  224. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_lime.png +0 -0
  225. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_magenta.png +0 -0
  226. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_orange.png +0 -0
  227. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_pink.png +0 -0
  228. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_purple.png +0 -0
  229. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_red.png +0 -0
  230. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_white.png +0 -0
  231. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_yellow.png +0 -0
  232. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/barrier.png +0 -0
  233. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/end_portal.png +0 -0
  234. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/grass.png +0 -0
  235. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png +0 -0
  236. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/structure_void.png +0 -0
  237. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png +0 -0
  238. amulet/resource_pack/java/java_vanilla_fix/pack.png +0 -0
  239. amulet/resource_pack/java/resource_pack.py +0 -44
  240. amulet/resource_pack/java/resource_pack_manager.py +0 -563
  241. amulet/resource_pack/unknown_resource_pack.py +0 -10
  242. amulet/selection/__init__.py +0 -2
  243. amulet/selection/abstract_selection.py +0 -342
  244. amulet/selection/box.py +0 -852
  245. amulet/selection/group.py +0 -481
  246. amulet/utils/__init__.pyi +0 -23
  247. amulet/utils/call_spec/__init__.py +0 -24
  248. amulet/utils/call_spec/_call_spec.py +0 -257
  249. amulet/utils/cast.py +0 -10
  250. amulet/utils/comment_json.py +0 -188
  251. amulet/utils/format_utils.py +0 -41
  252. amulet/utils/generator.py +0 -18
  253. amulet/utils/matrix.py +0 -243
  254. amulet/utils/numpy.hpp +0 -36
  255. amulet/utils/numpy.pyi +0 -11
  256. amulet/utils/numpy_helpers.py +0 -19
  257. amulet/utils/shareable_lock.py +0 -335
  258. amulet/utils/signal/__init__.py +0 -10
  259. amulet/utils/signal/_signal.py +0 -228
  260. amulet/utils/task_manager.py +0 -235
  261. amulet/utils/typed_property.py +0 -111
  262. amulet/utils/weakref.py +0 -70
  263. amulet/utils/world_utils.py +0 -102
  264. amulet/version.cpp +0 -136
  265. amulet/version.hpp +0 -142
  266. amulet/version.py.cpp +0 -281
  267. amulet_core-2.0a8.dist-info/RECORD +0 -241
  268. amulet_core-2.0a8.dist-info/entry_points.txt +0 -2
  269. /amulet/{__pyinstaller → core/__pyinstaller}/__init__.py +0 -0
  270. /amulet/{py.typed → core/py.typed} +0 -0
  271. {amulet_core-2.0a8.dist-info → amulet_core-2.0.1a2.post250529084738.dist-info}/top_level.txt +0 -0
@@ -1,86 +0,0 @@
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()
@@ -1,507 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import BinaryIO, Callable
4
- import copy
5
- from threading import RLock
6
- import logging
7
- from dataclasses import dataclass
8
- import shutil
9
- import time
10
- import glob
11
- import json
12
- import struct
13
- import os
14
-
15
- import portalocker
16
-
17
- from amulet_nbt import (
18
- IntTag,
19
- LongTag,
20
- StringTag,
21
- ListTag,
22
- CompoundTag,
23
- read_nbt,
24
- NamedTag,
25
- )
26
-
27
- from amulet.data_types import DimensionId
28
- from amulet.block import BlockStack, Block
29
- from amulet.biome import Biome
30
- from amulet.game import get_game_version
31
- from amulet.selection import SelectionGroup, SelectionBox
32
- from amulet.errors import LevelWriteError
33
- from amulet.level.abc import (
34
- RawLevel,
35
- IdRegistry,
36
- )
37
- from amulet.version import VersionNumber
38
- from amulet.utils.signal import Signal, SignalInstanceCacheName
39
- from amulet.utils.weakref import DetachableWeakRef
40
-
41
- from amulet.level.java.anvil import AnvilDimension
42
- from ._data_pack import DataPackManager, DataPack
43
- from ._dimension import JavaRawDimension
44
- from ._typing import InternalDimensionId
45
- from ._constant import OVERWORLD, THE_NETHER, THE_END, DefaultSelection
46
-
47
-
48
- log = logging.getLogger(__name__)
49
-
50
-
51
- @dataclass
52
- class JavaCreateArgsV1:
53
- """A class to house call arguments to create.
54
-
55
- If the call arguments to create need to be modified in the future a new arguments class can be created.
56
- The create method can inspect which class it was given and access arguments accordingly.
57
- """
58
-
59
- overwrite: bool
60
- path: str
61
- version: VersionNumber
62
- level_name: str
63
-
64
-
65
- class JavaRawLevelOpenData:
66
- back_reference: Callable[[], JavaRawLevel | None]
67
- detach_back_reference: Callable[[], None]
68
- lock_file: BinaryIO
69
- lock_time: float
70
- data_pack: DataPackManager
71
- dimensions: dict[InternalDimensionId, JavaRawDimension]
72
- dimension_ids: dict[DimensionId, InternalDimensionId]
73
- dimensions_lock: RLock
74
- block_id_override: IdRegistry
75
- biome_id_override: IdRegistry
76
-
77
- def __init__(
78
- self,
79
- raw_level: JavaRawLevel,
80
- lock_file: BinaryIO,
81
- lock_time: float,
82
- data_pack: DataPackManager,
83
- ) -> None:
84
- self.back_reference, self.detach_back_reference = DetachableWeakRef.new(
85
- raw_level
86
- )
87
- self.lock_file = lock_file
88
- self.lock_time = lock_time
89
- self.data_pack = data_pack
90
- self.dimensions = {}
91
- self.dimension_ids = {}
92
- self.dimensions_lock = RLock()
93
- self.block_id_override = IdRegistry()
94
- self.biome_id_override = IdRegistry()
95
-
96
-
97
- class JavaRawLevel(RawLevel[JavaRawDimension]):
98
- _path: str
99
- _level_dat: NamedTag
100
- _data_version: VersionNumber
101
- _raw_open_data: JavaRawLevelOpenData | None
102
-
103
- __slots__ = (
104
- "_path",
105
- "_level_dat",
106
- "_data_version",
107
- "_raw_open_data",
108
- SignalInstanceCacheName,
109
- )
110
-
111
- def __init__(self, _ikwiad: bool = False) -> None:
112
- if not _ikwiad:
113
- raise RuntimeError(
114
- "JavaRawLevel must be constructed using the create or load classmethod."
115
- )
116
-
117
- @classmethod
118
- def load(cls, path: str) -> JavaRawLevel:
119
- self = cls(True)
120
- self._path = path
121
- self._raw_open_data = None
122
- self.reload()
123
- return self
124
-
125
- @classmethod
126
- def create(cls, args: JavaCreateArgsV1) -> JavaRawLevel:
127
- overwrite = args.overwrite
128
- path = args.path
129
- version = args.version
130
- level_name = args.level_name
131
-
132
- if os.path.isdir(path):
133
- if overwrite:
134
- shutil.rmtree(path)
135
- else:
136
- raise LevelWriteError(f"A world already exists at the path {path}")
137
- os.makedirs(path, exist_ok=True)
138
-
139
- data_version = get_game_version("java", version).max_version
140
-
141
- root = CompoundTag()
142
- root["Data"] = data = CompoundTag()
143
- data["version"] = IntTag(19133)
144
- data["DataVersion"] = IntTag(data_version[0])
145
- data["LastPlayed"] = LongTag(int(time.time() * 1000))
146
- data["LevelName"] = StringTag(level_name)
147
-
148
- root.save_to(os.path.join(path, "level.dat"))
149
-
150
- return cls.load(path)
151
-
152
- def is_open(self) -> bool:
153
- return self._raw_open_data is not None
154
-
155
- @property
156
- def _o(self) -> JavaRawLevelOpenData:
157
- o = self._raw_open_data
158
- if o is None:
159
- raise RuntimeError("The level is not open.")
160
- return o
161
-
162
- def _update_data_version(self) -> None:
163
- """Pull the data version from the level.dat file"""
164
- self._data_version = VersionNumber(
165
- self._level_dat.compound.get_compound("Data", CompoundTag())
166
- .get_int("DataVersion", IntTag(-1))
167
- .py_int
168
- )
169
-
170
- def reload(self) -> None:
171
- """Reload the raw level."""
172
- if self.is_open():
173
- raise RuntimeError("Cannot reload a level when it is open.")
174
- self._level_dat = read_nbt(os.path.join(self.path, "level.dat"))
175
- self._update_data_version()
176
-
177
- opened = Signal[()]()
178
-
179
- def open(self) -> None:
180
- """Open the raw level."""
181
- if self.is_open():
182
- return
183
-
184
- # create the session.lock file
185
- try:
186
- # Try to open the file
187
- lock = portalocker.Lock(
188
- os.path.join(self.path, "session.lock"),
189
- "wb+",
190
- fail_when_locked=True,
191
- )
192
- lock_file: BinaryIO = lock.acquire() # type: ignore
193
- except portalocker.LockException:
194
- raise Exception(
195
- f"Could not acquire session.lock. The world may be open somewhere else."
196
- )
197
- else:
198
- # write the current time to the file
199
- lock_time = time.time()
200
- lock_file.write(struct.pack(">Q", int(lock_time * 1000)))
201
-
202
- # flush the changes to disk
203
- lock_file.flush()
204
- os.fsync(lock_file.fileno())
205
-
206
- packs = []
207
- enabled_packs = (
208
- self.level_dat.compound.get_compound("Data", CompoundTag())
209
- .get_compound("DataPacks", CompoundTag())
210
- .get_list("Enabled", ListTag())
211
- )
212
- for pack in enabled_packs:
213
- if isinstance(pack, StringTag):
214
- pack_name: str = pack.py_str
215
- if pack_name == "vanilla":
216
- pass
217
- elif pack_name.startswith("file/"):
218
- path = os.path.join(self.path, "datapacks", pack_name[5:])
219
- if DataPack.is_path_valid(path):
220
- packs.append(DataPack(path))
221
- data_pack = DataPackManager(packs)
222
-
223
- self._raw_open_data = JavaRawLevelOpenData(
224
- self, lock_file, lock_time, data_pack
225
- )
226
- self.opened.emit()
227
-
228
- closed = Signal[()]()
229
-
230
- def close(self) -> None:
231
- """Close the raw level."""
232
- if not self.is_open():
233
- return
234
- open_data = self._o
235
- portalocker.unlock(open_data.lock_file)
236
- open_data.lock_file.close()
237
- open_data.detach_back_reference()
238
- self._raw_open_data = None
239
- self.closed.emit()
240
-
241
- @property
242
- def path(self) -> str:
243
- return self._path
244
-
245
- @property
246
- def level_dat(self) -> NamedTag:
247
- """Get the level.dat file for the world"""
248
- return copy.deepcopy(self._level_dat)
249
-
250
- @level_dat.setter
251
- def level_dat(self, level_dat: NamedTag) -> None:
252
- if not isinstance(level_dat, NamedTag):
253
- raise TypeError
254
- if not self.is_open():
255
- raise RuntimeError("Level is not open.")
256
- self._level_dat = level_dat = copy.deepcopy(level_dat)
257
- self._update_data_version()
258
- level_dat.save_to(os.path.join(self.path, "level.dat"))
259
-
260
- @property
261
- def platform(self) -> str:
262
- return "java"
263
-
264
- @property
265
- def data_version(self) -> VersionNumber:
266
- """
267
- The game data version that the level was last opened in.
268
- This is used to determine the data format to save in.
269
- """
270
- return self._data_version
271
-
272
- @property
273
- def modified_time(self) -> float:
274
- """Unix timestamp of when the level was last modified."""
275
- return (
276
- self.level_dat.compound.get_compound("Data", CompoundTag())
277
- .get_long("LastPlayed", LongTag())
278
- .py_int
279
- / 1000
280
- )
281
-
282
- @property
283
- def level_name(self) -> str:
284
- return (
285
- self._level_dat.compound.get_compound("Data", CompoundTag())
286
- .get_string("LevelName", StringTag("Undefined"))
287
- .py_str
288
- )
289
-
290
- @level_name.setter
291
- def level_name(self, value: str) -> None:
292
- level_dat = self.level_dat
293
- level_dat.compound.setdefault_compound("Data")["LevelName"] = StringTag(value)
294
- self.level_dat = level_dat
295
-
296
- def _get_dimension_bounds(self, dimension_type_str: DimensionId) -> SelectionGroup:
297
- if self._data_version >= VersionNumber(2709): # This number might be smaller
298
- # If in a version that supports custom height data packs
299
- dimension_settings = (
300
- self.level_dat.compound.get_compound("Data", CompoundTag())
301
- .get_compound("WorldGenSettings", CompoundTag())
302
- .get_compound("dimensions", CompoundTag())
303
- .get_compound(dimension_type_str, CompoundTag())
304
- )
305
-
306
- # "type" can be a reference (string) or inline (compound) dimension-type data.
307
- dimension_type = dimension_settings.get("type")
308
-
309
- if isinstance(dimension_type, StringTag):
310
- # Reference type. Load the dimension data
311
- dimension_type_str = dimension_type.py_str
312
- if ":" in dimension_type_str:
313
- namespace, base_name = dimension_type_str.split(":", 1)
314
- else:
315
- namespace = "minecraft"
316
- base_name = dimension_type_str
317
- name_tuple = namespace, base_name
318
-
319
- # First try and load the reference from the data pack and then from defaults
320
- dimension_path = f"data/{namespace}/dimension_type/{base_name}.json"
321
- if self._o.data_pack.has_file(dimension_path):
322
- with self._o.data_pack.open(dimension_path) as d:
323
- try:
324
- dimension_settings_json = json.load(d)
325
- except json.JSONDecodeError:
326
- pass
327
- else:
328
- if "min_y" in dimension_settings_json and isinstance(
329
- dimension_settings_json["min_y"], int
330
- ):
331
- min_y = dimension_settings_json["min_y"]
332
- if min_y % 16:
333
- min_y = 16 * (min_y // 16)
334
- else:
335
- min_y = 0
336
- if "height" in dimension_settings_json and isinstance(
337
- dimension_settings_json["height"], int
338
- ):
339
- height = dimension_settings_json["height"]
340
- if height % 16:
341
- height = -16 * (-height // 16)
342
- else:
343
- height = 256
344
-
345
- return SelectionGroup(
346
- SelectionBox(
347
- (-30_000_000, min_y, -30_000_000),
348
- (30_000_000, min_y + height, 30_000_000),
349
- )
350
- )
351
-
352
- elif name_tuple in {
353
- ("minecraft", "overworld"),
354
- ("minecraft", "overworld_caves"),
355
- }:
356
- if self.data_version >= VersionNumber(2825):
357
- # If newer than the height change version
358
- return SelectionGroup(
359
- SelectionBox(
360
- (-30_000_000, -64, -30_000_000),
361
- (30_000_000, 320, 30_000_000),
362
- )
363
- )
364
- else:
365
- return DefaultSelection
366
- elif name_tuple in {
367
- ("minecraft", "the_nether"),
368
- ("minecraft", "the_end"),
369
- }:
370
- return DefaultSelection
371
- else:
372
- log.error(f"Could not find dimension_type {':'.join(name_tuple)}")
373
-
374
- elif isinstance(dimension_type, CompoundTag):
375
- # Inline type
376
- dimension_type_compound = dimension_type
377
- min_y = (
378
- dimension_type_compound.get_int("min_y", IntTag()).py_int // 16
379
- ) * 16
380
- height = (
381
- -dimension_type_compound.get_int("height", IntTag(256)).py_int // 16
382
- ) * -16
383
- return SelectionGroup(
384
- SelectionBox(
385
- (-30_000_000, min_y, -30_000_000),
386
- (30_000_000, min_y + height, 30_000_000),
387
- )
388
- )
389
- else:
390
- log.error(
391
- f'level_dat["Data"]["WorldGenSettings"]["dimensions"]["{dimension_type_str}"]["type"] was not a StringTag or CompoundTag.'
392
- )
393
-
394
- # Return the default if nothing else returned
395
- return DefaultSelection
396
-
397
- def _register_dimension(
398
- self,
399
- relative_dimension_path: InternalDimensionId,
400
- dimension_name: DimensionId,
401
- ) -> None:
402
- """
403
- Register a new dimension.
404
-
405
- :param relative_dimension_path: The relative path to the dimension directory from the world root.
406
- "" for the world root.
407
- :param dimension_name: The name of the dimension shown to the user
408
- """
409
- if relative_dimension_path:
410
- path = os.path.join(self.path, relative_dimension_path)
411
- else:
412
- path = self.path
413
-
414
- if (
415
- relative_dimension_path not in self._o.dimensions
416
- and dimension_name not in self._o.dimension_ids
417
- ):
418
- self._o.dimension_ids[dimension_name] = relative_dimension_path
419
- self._o.dimensions[relative_dimension_path] = JavaRawDimension(
420
- self._o.back_reference,
421
- # TODO: The data version can change while the level is open.
422
- # That may cause problems with this.
423
- AnvilDimension(
424
- path,
425
- mcc=self.data_version > VersionNumber(2203),
426
- layers=("region",)
427
- + ("entities",) * (self.data_version >= VersionNumber(2681)),
428
- ),
429
- relative_dimension_path,
430
- dimension_name,
431
- self._get_dimension_bounds(dimension_name),
432
- # TODO: Is this data stored somewhere?
433
- BlockStack(Block("java", VersionNumber(3700), "minecraft", "air")),
434
- (
435
- Biome("java", VersionNumber(3700), "minecraft", "nether_wastes")
436
- if dimension_name == THE_NETHER
437
- else (
438
- Biome("java", VersionNumber(3700), "minecraft", "the_end")
439
- if dimension_name == THE_END
440
- else Biome("java", VersionNumber(3700), "minecraft", "plains")
441
- )
442
- ),
443
- )
444
-
445
- def _find_dimensions(self) -> None:
446
- with self._o.dimensions_lock:
447
- if self._o.dimensions:
448
- return
449
-
450
- # load all the levels
451
- self._register_dimension("", OVERWORLD)
452
- self._register_dimension("DIM-1", THE_NETHER)
453
- self._register_dimension("DIM1", THE_END)
454
-
455
- for level_path in glob.glob(os.path.join(glob.escape(self.path), "DIM*")):
456
- if os.path.isdir(level_path):
457
- dir_name = os.path.basename(level_path)
458
- if AnvilDimension.level_regex.fullmatch(dir_name) is None:
459
- continue
460
- self._register_dimension(dir_name, dir_name)
461
-
462
- for region_path in glob.glob(
463
- os.path.join(
464
- glob.escape(self.path), "dimensions", "*", "*", "**", "region"
465
- ),
466
- recursive=True,
467
- ):
468
- if not os.path.isdir(region_path):
469
- continue
470
- dimension_path = os.path.dirname(region_path)
471
- rel_dim_path = os.path.relpath(dimension_path, self.path)
472
- _, dimension, *base_name = rel_dim_path.split(os.sep)
473
-
474
- dimension_name = f"{dimension}:{'/'.join(base_name)}"
475
- self._register_dimension(rel_dim_path, dimension_name)
476
-
477
- def dimension_ids(self) -> frozenset[DimensionId]:
478
- self._find_dimensions()
479
- return frozenset(self._o.dimension_ids)
480
-
481
- def get_dimension(self, dimension_id: DimensionId) -> JavaRawDimension:
482
- self._find_dimensions()
483
- internal_dimension_id = self._o.dimension_ids.get(dimension_id, dimension_id)
484
- if internal_dimension_id not in self._o.dimensions:
485
- raise RuntimeError(f"Dimension {dimension_id} does not exist")
486
- return self._o.dimensions[internal_dimension_id]
487
-
488
- def compact(self) -> None:
489
- """Compact all region files"""
490
- for dimension_id in self.dimension_ids():
491
- self.get_dimension(dimension_id).compact()
492
-
493
- @property
494
- def block_id_override(self) -> IdRegistry:
495
- """
496
- A two-way map from hard coded numerical block id <-> block string.
497
- This only stores overridden values. If the value is not present here you should check the translator.
498
- """
499
- return self._o.block_id_override
500
-
501
- @property
502
- def biome_id_override(self) -> IdRegistry:
503
- """
504
- A two-way map from hard coded numerical biome id <-> biome string.
505
- This only stores overridden values. If the value is not present here you should check the translator.
506
- """
507
- return self._o.biome_id_override
@@ -1,3 +0,0 @@
1
- from typing import TypeAlias
2
-
3
- InternalDimensionId: TypeAlias = str