amulet-core 2.0a7__cp312-cp312-win_amd64.whl → 2.0.1a2.post250529084747__cp312-cp312-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of amulet-core might be problematic. Click here for more details.

Files changed (325) hide show
  1. amulet/core/__init__.py +36 -0
  2. amulet/core/__pyinstaller/hook-amulet.core.py +4 -0
  3. amulet/core/_amulet_core.cp312-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.0a7.dist-info → amulet_core-2.0.1a2.post250529084747.dist-info}/METADATA +25 -20
  40. amulet_core-2.0.1a2.post250529084747.dist-info/RECORD +45 -0
  41. {amulet_core-2.0a7.dist-info → amulet_core-2.0.1a2.post250529084747.dist-info}/WHEEL +1 -1
  42. amulet_core-2.0.1a2.post250529084747.dist-info/entry_points.txt +2 -0
  43. amulet/__init__.cp312-win_amd64.pyd +0 -0
  44. amulet/__init__.py.cpp +0 -43
  45. amulet/__init__.pyi +0 -28
  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 -99
  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 -335
  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__.py +0 -1
  195. amulet/mesh/block/block_mesh.py +0 -369
  196. amulet/mesh/block/cube.py +0 -149
  197. amulet/mesh/block/missing_block.py +0 -20
  198. amulet/mesh/util.py +0 -17
  199. amulet/palette/biome_palette.hpp +0 -85
  200. amulet/palette/block_palette.cpp +0 -32
  201. amulet/palette/block_palette.hpp +0 -93
  202. amulet/player.py +0 -62
  203. amulet/pybind11/collections.hpp +0 -118
  204. amulet/pybind11/numpy.hpp +0 -26
  205. amulet/pybind11/py_module.hpp +0 -34
  206. amulet/pybind11/type_hints.hpp +0 -51
  207. amulet/pybind11/types.hpp +0 -25
  208. amulet/pybind11/typing.hpp +0 -7
  209. amulet/resource_pack/__init__.py +0 -62
  210. amulet/resource_pack/abc/__init__.py +0 -2
  211. amulet/resource_pack/abc/resource_pack.py +0 -38
  212. amulet/resource_pack/abc/resource_pack_manager.py +0 -87
  213. amulet/resource_pack/bedrock/__init__.py +0 -2
  214. amulet/resource_pack/bedrock/bedrock_vanilla_fix/pack_icon.png +0 -0
  215. amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/grass_carried.png +0 -0
  216. amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/grass_side_carried.png +0 -0
  217. amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/water.png +0 -0
  218. amulet/resource_pack/bedrock/blockshapes/__init__.py +0 -31
  219. amulet/resource_pack/bedrock/blockshapes/air.py +0 -35
  220. amulet/resource_pack/bedrock/blockshapes/base_blockshape.py +0 -29
  221. amulet/resource_pack/bedrock/blockshapes/bubble_column.py +0 -29
  222. amulet/resource_pack/bedrock/blockshapes/cake.py +0 -46
  223. amulet/resource_pack/bedrock/blockshapes/chest.py +0 -54
  224. amulet/resource_pack/bedrock/blockshapes/comparator.py +0 -51
  225. amulet/resource_pack/bedrock/blockshapes/cross_texture.py +0 -186
  226. amulet/resource_pack/bedrock/blockshapes/cross_texture0.py +0 -17
  227. amulet/resource_pack/bedrock/blockshapes/cross_texture_green.py +0 -16
  228. amulet/resource_pack/bedrock/blockshapes/cube.py +0 -38
  229. amulet/resource_pack/bedrock/blockshapes/default.py +0 -14
  230. amulet/resource_pack/bedrock/blockshapes/door.py +0 -38
  231. amulet/resource_pack/bedrock/blockshapes/door1.py +0 -14
  232. amulet/resource_pack/bedrock/blockshapes/door2.py +0 -14
  233. amulet/resource_pack/bedrock/blockshapes/door3.py +0 -14
  234. amulet/resource_pack/bedrock/blockshapes/door4.py +0 -14
  235. amulet/resource_pack/bedrock/blockshapes/door5.py +0 -14
  236. amulet/resource_pack/bedrock/blockshapes/door6.py +0 -14
  237. amulet/resource_pack/bedrock/blockshapes/double_plant.py +0 -40
  238. amulet/resource_pack/bedrock/blockshapes/enchanting_table.py +0 -22
  239. amulet/resource_pack/bedrock/blockshapes/farmland.py +0 -22
  240. amulet/resource_pack/bedrock/blockshapes/fence.py +0 -22
  241. amulet/resource_pack/bedrock/blockshapes/flat.py +0 -55
  242. amulet/resource_pack/bedrock/blockshapes/flat_wall.py +0 -55
  243. amulet/resource_pack/bedrock/blockshapes/furnace.py +0 -44
  244. amulet/resource_pack/bedrock/blockshapes/furnace_lit.py +0 -14
  245. amulet/resource_pack/bedrock/blockshapes/green_cube.py +0 -39
  246. amulet/resource_pack/bedrock/blockshapes/ladder.py +0 -36
  247. amulet/resource_pack/bedrock/blockshapes/lilypad.py +0 -14
  248. amulet/resource_pack/bedrock/blockshapes/partial_block.py +0 -57
  249. amulet/resource_pack/bedrock/blockshapes/piston.py +0 -44
  250. amulet/resource_pack/bedrock/blockshapes/piston_arm.py +0 -72
  251. amulet/resource_pack/bedrock/blockshapes/portal_frame.py +0 -22
  252. amulet/resource_pack/bedrock/blockshapes/pressure_plate.py +0 -29
  253. amulet/resource_pack/bedrock/blockshapes/pumpkin.py +0 -36
  254. amulet/resource_pack/bedrock/blockshapes/pumpkin_carved.py +0 -14
  255. amulet/resource_pack/bedrock/blockshapes/pumpkin_lit.py +0 -14
  256. amulet/resource_pack/bedrock/blockshapes/red_dust.py +0 -14
  257. amulet/resource_pack/bedrock/blockshapes/repeater.py +0 -53
  258. amulet/resource_pack/bedrock/blockshapes/slab.py +0 -33
  259. amulet/resource_pack/bedrock/blockshapes/slab_double.py +0 -15
  260. amulet/resource_pack/bedrock/blockshapes/tree.py +0 -41
  261. amulet/resource_pack/bedrock/blockshapes/turtle_egg.py +0 -15
  262. amulet/resource_pack/bedrock/blockshapes/vine.py +0 -52
  263. amulet/resource_pack/bedrock/blockshapes/wall.py +0 -22
  264. amulet/resource_pack/bedrock/blockshapes/water.py +0 -38
  265. amulet/resource_pack/bedrock/download_resources.py +0 -147
  266. amulet/resource_pack/bedrock/resource_pack.py +0 -40
  267. amulet/resource_pack/bedrock/resource_pack_manager.py +0 -361
  268. amulet/resource_pack/bedrock/sort_blockshapes.py +0 -15
  269. amulet/resource_pack/java/__init__.py +0 -2
  270. amulet/resource_pack/java/download_resources.py +0 -212
  271. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_black.png +0 -0
  272. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_blue.png +0 -0
  273. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_brown.png +0 -0
  274. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_cyan.png +0 -0
  275. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_gray.png +0 -0
  276. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_green.png +0 -0
  277. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_blue.png +0 -0
  278. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_gray.png +0 -0
  279. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_lime.png +0 -0
  280. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_magenta.png +0 -0
  281. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_orange.png +0 -0
  282. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_pink.png +0 -0
  283. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_purple.png +0 -0
  284. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_red.png +0 -0
  285. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_white.png +0 -0
  286. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_yellow.png +0 -0
  287. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/barrier.png +0 -0
  288. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/end_portal.png +0 -0
  289. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/grass.png +0 -0
  290. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png +0 -0
  291. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/structure_void.png +0 -0
  292. amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png +0 -0
  293. amulet/resource_pack/java/java_vanilla_fix/pack.png +0 -0
  294. amulet/resource_pack/java/resource_pack.py +0 -44
  295. amulet/resource_pack/java/resource_pack_manager.py +0 -551
  296. amulet/resource_pack/unknown_resource_pack.py +0 -10
  297. amulet/selection/__init__.py +0 -2
  298. amulet/selection/abstract_selection.py +0 -342
  299. amulet/selection/box.py +0 -852
  300. amulet/selection/group.py +0 -481
  301. amulet/utils/__init__.pyi +0 -23
  302. amulet/utils/call_spec/__init__.py +0 -24
  303. amulet/utils/call_spec/_call_spec.py +0 -257
  304. amulet/utils/comment_json.py +0 -188
  305. amulet/utils/format_utils.py +0 -41
  306. amulet/utils/generator.py +0 -18
  307. amulet/utils/matrix.py +0 -243
  308. amulet/utils/numpy.hpp +0 -36
  309. amulet/utils/numpy.pyi +0 -11
  310. amulet/utils/numpy_helpers.py +0 -19
  311. amulet/utils/shareable_lock.py +0 -335
  312. amulet/utils/signal/__init__.py +0 -10
  313. amulet/utils/signal/_signal.py +0 -228
  314. amulet/utils/task_manager.py +0 -235
  315. amulet/utils/typed_property.py +0 -111
  316. amulet/utils/weakref.py +0 -70
  317. amulet/utils/world_utils.py +0 -102
  318. amulet/version.cpp +0 -136
  319. amulet/version.hpp +0 -142
  320. amulet/version.py.cpp +0 -281
  321. amulet_core-2.0a7.dist-info/RECORD +0 -295
  322. amulet_core-2.0a7.dist-info/entry_points.txt +0 -2
  323. /amulet/{__pyinstaller → core/__pyinstaller}/__init__.py +0 -0
  324. /amulet/{py.typed → core/py.typed} +0 -0
  325. {amulet_core-2.0a7.dist-info → amulet_core-2.0.1a2.post250529084747.dist-info}/top_level.txt +0 -0
amulet/level/_load.py DELETED
@@ -1,100 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import Type, Any
4
- import logging
5
- from inspect import isclass
6
- from threading import Lock
7
- from weakref import WeakValueDictionary
8
-
9
- from amulet.level.abc import LoadableLevel
10
-
11
-
12
- log = logging.getLogger(__name__)
13
-
14
-
15
- _level_classes = set[Type[LoadableLevel]]()
16
- _levels = WeakValueDictionary[Any, LoadableLevel]()
17
- _lock = Lock()
18
-
19
-
20
- def _check_loadable_level(cls: Any) -> None:
21
- if not (isclass(cls) and issubclass(cls, LoadableLevel)):
22
- raise TypeError(
23
- "cls must be a subclass of amulet.level.abc.Level and amulet.level.abc.LoadableLevel"
24
- )
25
-
26
-
27
- def register_level_class(cls: Type[LoadableLevel]) -> None:
28
- """Add a level class to be considered when getting a level.
29
-
30
- :param cls: The Level subclass to register.
31
- :return:
32
- """
33
- _check_loadable_level(cls)
34
- with _lock:
35
- _level_classes.add(cls)
36
-
37
-
38
- def unregister_level_class(cls: Type[LoadableLevel]) -> None:
39
- """Remove a level class from consideration when getting a level.
40
-
41
- Note that any instances of the class will remain.
42
-
43
- :param cls: The Level subclass to unregister.
44
- """
45
- _check_loadable_level(cls)
46
- with _lock:
47
- _level_classes.discard(cls)
48
-
49
-
50
- class NoValidLevel(Exception):
51
- """An error thrown if no level could load the token."""
52
-
53
- pass
54
-
55
-
56
- def get_level(token: Any) -> LoadableLevel:
57
- """Get the level for the given token.
58
-
59
- If a level object already exists for this token then that will be returned.
60
- This will return a subclass of Level specialised for that level type.
61
- Note that the returned level may or may not be open.
62
- The level will automatically close itself when the last reference is lost so you must hold a strong reference to it.
63
-
64
- :param token: The token to load. This may be a file/directory path or some other token.
65
- :return: The level instance.
66
- :raises:
67
- NoValidLevel: If no level could load the token.
68
-
69
- Exception: Other errors.
70
- """
71
- level: None | LoadableLevel
72
- with _lock:
73
- # Find the level to load the token
74
- cls = next((cls for cls in _level_classes if cls.can_load(token)), None)
75
-
76
- if cls is None:
77
- # If no level could load the token then raise
78
- raise NoValidLevel(f"Could not load {token}")
79
-
80
- try:
81
- # Try and get a cached instance of the level
82
- level = _levels.get(token)
83
- if level is not None:
84
- # If there is a cached instance then return it
85
- return level
86
- except TypeError:
87
- # If the token is not hashable
88
- pass
89
-
90
- # Load the level
91
- level = cls.load(token)
92
-
93
- try:
94
- # Cache the level
95
- _levels[token] = level
96
- except TypeError:
97
- # Token may not be hashable
98
- pass
99
-
100
- return level
@@ -1,12 +0,0 @@
1
- from ._level import *
2
- from ._chunk_handle import ChunkHandle
3
- from ._player_storage import PlayerStorage
4
- from ._raw_level import (
5
- RawLevel,
6
- RawLevelFriend,
7
- RawLevelPlayerComponent,
8
- RawLevelBufferedComponent,
9
- RawDimension,
10
- )
11
- from ._dimension import Dimension
12
- from ._registry import IdRegistry
@@ -1,335 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import pickle
4
- from typing import Optional, TYPE_CHECKING, Generic, TypeVar, Callable, Self
5
- from collections.abc import Iterator, Iterable
6
- from contextlib import contextmanager
7
- from threading import RLock
8
- from abc import ABC, abstractmethod
9
-
10
- from amulet.utils.shareable_lock import LockNotAcquired
11
- from amulet.chunk import Chunk, get_null_chunk
12
- from amulet.data_types import DimensionId
13
- from amulet.errors import ChunkDoesNotExist, ChunkLoadError
14
- from amulet.utils.signal import Signal
15
-
16
- from ._level import LevelFriend, LevelT
17
- from ._history import HistoryManagerLayer
18
-
19
-
20
- if TYPE_CHECKING:
21
- from ._level import Level
22
- from ._raw_level import RawDimension
23
-
24
-
25
- ChunkT = TypeVar("ChunkT", bound=Chunk)
26
- RawDimensionT = TypeVar("RawDimensionT", bound="RawDimension")
27
-
28
-
29
- class ChunkKey(tuple[int, int]):
30
- def __new__(cls, cx: int, cz: int) -> Self:
31
- return tuple.__new__(cls, (cx, cz))
32
-
33
- def __init__(self, cx: int, cz: int) -> None:
34
- self._bytes: Optional[bytes] = None
35
-
36
- @property
37
- def cx(self) -> int:
38
- return self[0]
39
-
40
- @property
41
- def cz(self) -> int:
42
- return self[1]
43
-
44
- def __bytes__(self) -> bytes:
45
- if self._bytes is None:
46
- self._bytes = b"/".join((str(self[0]).encode(), str(self[1]).encode()))
47
- return self._bytes
48
-
49
-
50
- class ChunkHandle(
51
- LevelFriend[LevelT],
52
- ABC,
53
- Generic[LevelT, RawDimensionT, ChunkT],
54
- ):
55
- """
56
- A class which manages chunk data.
57
- You must acquire the lock for the chunk before reading or writing data.
58
- Some internal synchronisation is done to catch some threading issues.
59
- """
60
-
61
- _lock: RLock
62
- _dimension: DimensionId
63
- _key: ChunkKey
64
- _chunk_history: HistoryManagerLayer[ChunkKey]
65
- _chunk_data_history: HistoryManagerLayer[bytes]
66
- _raw_dimension: Optional[RawDimensionT]
67
-
68
- __slots__ = (
69
- "_lock",
70
- "_dimension_id",
71
- "_key",
72
- "_chunk_history",
73
- "_chunk_data_history",
74
- "_raw_dimension",
75
- )
76
-
77
- def __init__(
78
- self,
79
- level_ref: Callable[[], LevelT | None],
80
- chunk_history: HistoryManagerLayer[ChunkKey],
81
- chunk_data_history: HistoryManagerLayer[bytes],
82
- dimension_id: DimensionId,
83
- cx: int,
84
- cz: int,
85
- ) -> None:
86
- super().__init__(level_ref)
87
- self._lock = RLock()
88
- self._dimension_id = dimension_id
89
- self._key = ChunkKey(cx, cz)
90
- self._chunk_history = chunk_history
91
- self._chunk_data_history = chunk_data_history
92
- self._raw_dimension = None
93
-
94
- changed = Signal[()]()
95
-
96
- @property
97
- def dimension_id(self) -> DimensionId:
98
- return self._dimension_id
99
-
100
- @property
101
- def cx(self) -> int:
102
- return self._key.cx
103
-
104
- @property
105
- def cz(self) -> int:
106
- return self._key.cz
107
-
108
- def _get_raw_dimension(self) -> RawDimensionT:
109
- if self._raw_dimension is None:
110
- self._raw_dimension = self._l.raw.get_dimension(self.dimension_id)
111
- return self._raw_dimension
112
-
113
- @contextmanager
114
- def lock(
115
- self,
116
- *,
117
- blocking: bool = True,
118
- timeout: float = -1,
119
- ) -> Iterator[None]:
120
- """
121
- Lock access to the chunk.
122
-
123
- >>> level: Level
124
- >>> dimension_name: str
125
- >>> cx: int
126
- >>> cz: int
127
- >>> with level.get_dimension(dimension_name).get_chunk_handle(cx, cz).lock():
128
- >>> # Do what you need to with the chunk
129
- >>> # No other threads are able to edit or set the chunk while in this with block.
130
-
131
- If you want to lock, get and set the chunk data :meth:`edit` is probably a better fit.
132
-
133
- :param blocking: Should this block until the lock is acquired.
134
- :param timeout: The amount of time to wait for the lock.
135
- :raises:
136
- LockNotAcquired: If the lock could not be acquired.
137
- """
138
- if not self._lock.acquire(blocking, timeout):
139
- # Thread was not acquired
140
- raise LockNotAcquired("Lock was not acquired.")
141
- try:
142
- yield
143
- finally:
144
- self._lock.release()
145
-
146
- @contextmanager
147
- def edit(
148
- self,
149
- *,
150
- components: Iterable[str] | None = None,
151
- blocking: bool = True,
152
- timeout: float = -1,
153
- ) -> Iterator[ChunkT | None]:
154
- """Lock and edit a chunk.
155
-
156
- If you only want to access/modify parts of the chunk data you can specify the components you want to load.
157
- This makes it faster because you don't need to load unneeded parts.
158
-
159
- >>> level: Level
160
- >>> dimension_name: str
161
- >>> cx: int
162
- >>> cz: int
163
- >>> with level.get_dimension(dimension_name).get_chunk_handle(cx, cz).edit() as chunk:
164
- >>> # Edit the chunk data
165
- >>> # No other threads are able to edit the chunk while in this with block.
166
- >>> # When the with block exits the edited chunk will be automatically set if no exception occurred.
167
-
168
- :param components: None to load all components or an iterable of component strings to load.
169
- :param blocking: Should this block until the lock is acquired.
170
- :param timeout: The amount of time to wait for the lock.
171
- :raises:
172
- LockNotAcquired: If the lock could not be acquired.
173
- """
174
- with self.lock(blocking=blocking, timeout=timeout):
175
- chunk = self.get(components)
176
- yield chunk
177
- # If an exception occurs in user code, this line won't be run.
178
- self._set(chunk)
179
- self.changed.emit()
180
- self._l.changed.emit()
181
-
182
- def exists(self) -> bool:
183
- """
184
- Does the chunk exist. This is a quick way to check if the chunk exists without loading it.
185
-
186
- This state may change if the lock is not acquired.
187
-
188
- :return: True if the chunk exists. Calling get on this chunk handle may still throw ChunkLoadError
189
- """
190
- if self._chunk_history.has_resource(self._key):
191
- return self._chunk_history.resource_exists(self._key)
192
- else:
193
- # The history system is not aware of the chunk. Look in the level data
194
- return self._get_raw_dimension().has_chunk(self.cx, self.cz)
195
-
196
- def _preload(self) -> None:
197
- """Load the chunk data if it has not already been loaded."""
198
- if not self._chunk_history.has_resource(self._key):
199
- # The history system is not aware of the chunk. Load from the level data
200
- chunk: Chunk
201
- try:
202
- raw_chunk = self._get_raw_dimension().get_raw_chunk(self.cx, self.cz)
203
- chunk = self._get_raw_dimension().raw_chunk_to_native_chunk(
204
- raw_chunk,
205
- self.cx,
206
- self.cz,
207
- )
208
- except ChunkDoesNotExist:
209
- self._chunk_history.set_initial_resource(self._key, b"")
210
- except ChunkLoadError as e:
211
- self._chunk_history.set_initial_resource(self._key, pickle.dumps(e))
212
- else:
213
- self._chunk_history.set_initial_resource(
214
- self._key, pickle.dumps(chunk.chunk_id)
215
- )
216
- for component_id, component_data in chunk.serialise_chunk().items():
217
- if component_data is None:
218
- raise RuntimeError(
219
- "Component must not be None when initialising chunk"
220
- )
221
- self._chunk_data_history.set_initial_resource(
222
- b"/".join((bytes(self._key), component_id.encode())),
223
- component_data,
224
- )
225
-
226
- def _get_null_chunk(self) -> ChunkT:
227
- """Get a null chunk instance used for this chunk.
228
-
229
- :raises:
230
- ChunkDoesNotExist if the chunk does not exist.
231
- """
232
- data = self._chunk_history.get_resource(self._key)
233
- if data:
234
- obj: ChunkLoadError | str = pickle.loads(data)
235
- if isinstance(obj, ChunkLoadError):
236
- raise obj
237
- elif isinstance(obj, str):
238
- return get_null_chunk(obj) # type: ignore
239
- else:
240
- raise RuntimeError
241
- else:
242
- raise ChunkDoesNotExist
243
-
244
- def get_class(self) -> type[ChunkT]:
245
- """Get the chunk class used for this chunk.
246
-
247
- :raises:
248
- ChunkDoesNotExist if the chunk does not exist.
249
- """
250
- return type(self._get_null_chunk())
251
-
252
- def get(self, components: Iterable[str] | None = None) -> ChunkT:
253
- """Get a unique copy of the chunk data.
254
-
255
- If you want to edit the chunk, use :meth:`edit` instead.
256
-
257
- If you only want to access/modify parts of the chunk data you can specify the components you want to load.
258
- This makes it faster because you don't need to load unneeded parts.
259
-
260
- :param components: None to load all components or an iterable of component strings to load.
261
- :return: A unique copy of the chunk data.
262
- """
263
- with self.lock(blocking=False):
264
- self._preload()
265
- chunk = self._get_null_chunk()
266
- if components is None:
267
- components = chunk.component_ids
268
- else:
269
- # Ensure all component ids are valid for this class.
270
- components = set(components).intersection(chunk.component_ids)
271
- chunk_components = dict[str, bytes | None]()
272
- for component_id in components:
273
- chunk_components[component_id] = self._chunk_data_history.get_resource(
274
- b"/".join((bytes(self._key), component_id.encode()))
275
- )
276
- chunk.reconstruct_chunk(chunk_components)
277
- return chunk
278
-
279
- def _set(self, chunk: ChunkT | None) -> None:
280
- """Lock must be acquired before calling this"""
281
- history = self._chunk_history
282
- if not history.has_resource(self._key):
283
- if self._l.history_enabled:
284
- self._preload()
285
- else:
286
- history.set_initial_resource(self._key, b"")
287
- if chunk is None:
288
- history.set_resource(self._key, b"")
289
- else:
290
- self._validate_chunk(chunk)
291
- try:
292
- old_chunk_class = self.get_class()
293
- except ChunkLoadError:
294
- old_chunk_class = None
295
- new_chunk_class = type(chunk)
296
- component_data = chunk.serialise_chunk()
297
- if old_chunk_class != new_chunk_class and None in component_data.values():
298
- raise RuntimeError(
299
- "When changing chunk class all the data must be present."
300
- )
301
- history.set_resource(self._key, pickle.dumps(new_chunk_class))
302
- for component_id, data in component_data.items():
303
- if data is None:
304
- continue
305
- self._chunk_data_history.set_resource(
306
- b"/".join((bytes(self._key), component_id.encode())),
307
- data,
308
- )
309
-
310
- @staticmethod
311
- @abstractmethod
312
- def _validate_chunk(chunk: ChunkT) -> None:
313
- raise NotImplementedError
314
-
315
- def set(self, chunk: ChunkT) -> None:
316
- """
317
- Overwrite the chunk data.
318
- You must acquire the chunk lock before setting.
319
- If you want to edit the chunk, use :meth:`edit` instead.
320
-
321
- :param chunk: The chunk data to set.
322
- :raises:
323
- LockNotAcquired: If the chunk is already locked by another thread.
324
- """
325
- with self.lock(blocking=False):
326
- self._set(chunk)
327
- self.changed.emit()
328
- self._l.changed.emit()
329
-
330
- def delete(self) -> None:
331
- """Delete the chunk from the level."""
332
- with self.lock(blocking=False):
333
- self._set(None)
334
- self.changed.emit()
335
- self._l.changed.emit()
@@ -1,86 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from typing import Generic, TypeVar, Callable
3
- from weakref import WeakValueDictionary
4
- from threading import Lock
5
-
6
- from amulet.data_types import DimensionId
7
- from amulet.block import BlockStack
8
- from amulet.biome import Biome
9
- from amulet.selection import SelectionGroup
10
-
11
- from ._level import LevelFriend, LevelT
12
- from ._history import HistoryManagerLayer
13
- from ._chunk_handle import ChunkKey, ChunkHandle
14
- from ._raw_level import RawDimension
15
-
16
-
17
- ChunkHandleT = TypeVar("ChunkHandleT", bound=ChunkHandle)
18
- RawDimensionT = TypeVar("RawDimensionT", bound=RawDimension)
19
-
20
-
21
- class Dimension(LevelFriend[LevelT], ABC, Generic[LevelT, RawDimensionT, ChunkHandleT]):
22
- _dimension_id: DimensionId
23
- _chunk_handles: WeakValueDictionary[tuple[int, int], ChunkHandleT]
24
- _chunk_handle_lock: Lock
25
- _chunk_history: HistoryManagerLayer[ChunkKey]
26
- _chunk_data_history: HistoryManagerLayer[bytes]
27
- _raw: RawDimensionT
28
-
29
- def __init__(
30
- self, level_ref: Callable[[], LevelT | None], dimension_id: DimensionId
31
- ) -> None:
32
- super().__init__(level_ref)
33
- self._dimension_id = dimension_id
34
- self._chunk_handles = WeakValueDictionary()
35
- self._chunk_handle_lock = Lock()
36
- self._chunk_history = self._l._o.history_manager.new_layer()
37
- self._chunk_data_history = self._l._o.history_manager.new_layer()
38
- self._raw = self._l.raw.get_dimension(self._dimension_id)
39
-
40
- @property
41
- def dimension_id(self) -> DimensionId:
42
- return self._dimension_id
43
-
44
- def bounds(self) -> SelectionGroup:
45
- """The editable region of the dimension."""
46
- return self._raw.bounds()
47
-
48
- def default_block(self) -> BlockStack:
49
- """The default block for this dimension"""
50
- return self._raw.default_block()
51
-
52
- def default_biome(self) -> Biome:
53
- """The default biome for this dimension"""
54
- return self._raw.default_biome()
55
-
56
- def chunk_coords(self) -> set[tuple[int, int]]:
57
- """
58
- The coordinates of every chunk that exists in this dimension.
59
-
60
- This is the combination of chunks saved to the level and chunks yet to be saved.
61
- """
62
- chunks: set[tuple[int, int]] = set(self._raw.all_chunk_coords())
63
- for key, state in self._chunk_history.resources_exist_map().items():
64
- if state:
65
- chunks.add((key.cx, key.cz))
66
- else:
67
- chunks.discard((key.cx, key.cz))
68
- return chunks
69
-
70
- def changed_chunk_coords(self) -> set[tuple[int, int]]:
71
- """The coordinates of every chunk in this dimension that have been changed since the last save."""
72
- return {(key.cx, key.cz) for key in self._chunk_history.changed_resources()}
73
-
74
- @abstractmethod
75
- def _create_chunk_handle(self, cx: int, cz: int) -> ChunkHandleT:
76
- raise NotImplementedError
77
-
78
- def get_chunk_handle(self, cx: int, cz: int) -> ChunkHandleT:
79
- key = cx, cz
80
- with self._chunk_handle_lock:
81
- chunk_handle = self._chunk_handles.get(key)
82
- if chunk_handle is None:
83
- chunk_handle = self._chunk_handles[key] = self._create_chunk_handle(
84
- cx, cz
85
- )
86
- return chunk_handle
@@ -1 +0,0 @@
1
- from ._history_manager import HistoryManager, HistoryManagerLayer