amulet-core 1.9.19__py3-none-any.whl → 1.9.20__py3-none-any.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 (198) hide show
  1. amulet/__init__.py +27 -27
  2. amulet/__pyinstaller/__init__.py +2 -2
  3. amulet/__pyinstaller/hook-amulet.py +4 -4
  4. amulet/_version.py +21 -21
  5. amulet/api/__init__.py +2 -2
  6. amulet/api/abstract_base_entity.py +128 -128
  7. amulet/api/block.py +630 -630
  8. amulet/api/block_entity.py +71 -71
  9. amulet/api/cache.py +107 -107
  10. amulet/api/chunk/__init__.py +6 -6
  11. amulet/api/chunk/biomes.py +207 -207
  12. amulet/api/chunk/block_entity_dict.py +175 -175
  13. amulet/api/chunk/blocks.py +46 -46
  14. amulet/api/chunk/chunk.py +389 -389
  15. amulet/api/chunk/entity_list.py +75 -75
  16. amulet/api/chunk/status.py +167 -167
  17. amulet/api/data_types/__init__.py +4 -4
  18. amulet/api/data_types/generic_types.py +4 -4
  19. amulet/api/data_types/operation_types.py +16 -16
  20. amulet/api/data_types/world_types.py +49 -49
  21. amulet/api/data_types/wrapper_types.py +71 -71
  22. amulet/api/entity.py +74 -74
  23. amulet/api/errors.py +119 -119
  24. amulet/api/history/__init__.py +36 -36
  25. amulet/api/history/base/__init__.py +3 -3
  26. amulet/api/history/base/base_history.py +26 -26
  27. amulet/api/history/base/history_manager.py +63 -63
  28. amulet/api/history/base/revision_manager.py +73 -73
  29. amulet/api/history/changeable.py +15 -15
  30. amulet/api/history/data_types.py +7 -7
  31. amulet/api/history/history_manager/__init__.py +3 -3
  32. amulet/api/history/history_manager/container.py +102 -102
  33. amulet/api/history/history_manager/database.py +279 -279
  34. amulet/api/history/history_manager/meta.py +93 -93
  35. amulet/api/history/history_manager/object.py +116 -116
  36. amulet/api/history/revision_manager/__init__.py +2 -2
  37. amulet/api/history/revision_manager/disk.py +33 -33
  38. amulet/api/history/revision_manager/ram.py +12 -12
  39. amulet/api/item.py +75 -75
  40. amulet/api/level/__init__.py +4 -4
  41. amulet/api/level/base_level/__init__.py +1 -1
  42. amulet/api/level/base_level/base_level.py +1035 -1026
  43. amulet/api/level/base_level/chunk_manager.py +227 -227
  44. amulet/api/level/base_level/clone.py +389 -389
  45. amulet/api/level/base_level/player_manager.py +101 -101
  46. amulet/api/level/immutable_structure/__init__.py +1 -1
  47. amulet/api/level/immutable_structure/immutable_structure.py +94 -94
  48. amulet/api/level/immutable_structure/void_format_wrapper.py +117 -117
  49. amulet/api/level/structure.py +22 -22
  50. amulet/api/level/world.py +19 -19
  51. amulet/api/partial_3d_array/__init__.py +2 -2
  52. amulet/api/partial_3d_array/base_partial_3d_array.py +263 -263
  53. amulet/api/partial_3d_array/bounded_partial_3d_array.py +528 -528
  54. amulet/api/partial_3d_array/data_types.py +15 -15
  55. amulet/api/partial_3d_array/unbounded_partial_3d_array.py +229 -229
  56. amulet/api/partial_3d_array/util.py +152 -152
  57. amulet/api/player.py +65 -65
  58. amulet/api/registry/__init__.py +2 -2
  59. amulet/api/registry/base_registry.py +34 -34
  60. amulet/api/registry/biome_manager.py +153 -153
  61. amulet/api/registry/block_manager.py +156 -156
  62. amulet/api/selection/__init__.py +2 -2
  63. amulet/api/selection/abstract_selection.py +315 -315
  64. amulet/api/selection/box.py +805 -805
  65. amulet/api/selection/group.py +488 -488
  66. amulet/api/structure.py +37 -37
  67. amulet/api/wrapper/__init__.py +8 -8
  68. amulet/api/wrapper/chunk/interface.py +441 -441
  69. amulet/api/wrapper/chunk/translator.py +567 -567
  70. amulet/api/wrapper/format_wrapper.py +772 -772
  71. amulet/api/wrapper/structure_format_wrapper.py +116 -116
  72. amulet/api/wrapper/world_format_wrapper.py +63 -63
  73. amulet/level/__init__.py +1 -1
  74. amulet/level/formats/anvil_forge_world.py +40 -40
  75. amulet/level/formats/anvil_world/__init__.py +3 -3
  76. amulet/level/formats/anvil_world/_sector_manager.py +291 -384
  77. amulet/level/formats/anvil_world/data_pack/__init__.py +2 -2
  78. amulet/level/formats/anvil_world/data_pack/data_pack.py +224 -224
  79. amulet/level/formats/anvil_world/data_pack/data_pack_manager.py +77 -77
  80. amulet/level/formats/anvil_world/dimension.py +177 -177
  81. amulet/level/formats/anvil_world/format.py +769 -769
  82. amulet/level/formats/anvil_world/region.py +384 -384
  83. amulet/level/formats/construction/__init__.py +3 -3
  84. amulet/level/formats/construction/format_wrapper.py +515 -515
  85. amulet/level/formats/construction/interface.py +134 -134
  86. amulet/level/formats/construction/section.py +60 -60
  87. amulet/level/formats/construction/util.py +165 -165
  88. amulet/level/formats/leveldb_world/__init__.py +3 -3
  89. amulet/level/formats/leveldb_world/chunk.py +33 -33
  90. amulet/level/formats/leveldb_world/dimension.py +385 -419
  91. amulet/level/formats/leveldb_world/format.py +659 -641
  92. amulet/level/formats/leveldb_world/interface/chunk/__init__.py +36 -36
  93. amulet/level/formats/leveldb_world/interface/chunk/base_leveldb_interface.py +836 -836
  94. amulet/level/formats/leveldb_world/interface/chunk/generate_interface.py +31 -31
  95. amulet/level/formats/leveldb_world/interface/chunk/leveldb_0.py +30 -30
  96. amulet/level/formats/leveldb_world/interface/chunk/leveldb_1.py +12 -12
  97. amulet/level/formats/leveldb_world/interface/chunk/leveldb_10.py +12 -12
  98. amulet/level/formats/leveldb_world/interface/chunk/leveldb_11.py +12 -12
  99. amulet/level/formats/leveldb_world/interface/chunk/leveldb_12.py +12 -12
  100. amulet/level/formats/leveldb_world/interface/chunk/leveldb_13.py +12 -12
  101. amulet/level/formats/leveldb_world/interface/chunk/leveldb_14.py +12 -12
  102. amulet/level/formats/leveldb_world/interface/chunk/leveldb_15.py +12 -12
  103. amulet/level/formats/leveldb_world/interface/chunk/leveldb_16.py +12 -12
  104. amulet/level/formats/leveldb_world/interface/chunk/leveldb_17.py +12 -12
  105. amulet/level/formats/leveldb_world/interface/chunk/leveldb_18.py +12 -12
  106. amulet/level/formats/leveldb_world/interface/chunk/leveldb_19.py +12 -12
  107. amulet/level/formats/leveldb_world/interface/chunk/leveldb_2.py +12 -12
  108. amulet/level/formats/leveldb_world/interface/chunk/leveldb_20.py +12 -12
  109. amulet/level/formats/leveldb_world/interface/chunk/leveldb_21.py +12 -12
  110. amulet/level/formats/leveldb_world/interface/chunk/leveldb_22.py +12 -12
  111. amulet/level/formats/leveldb_world/interface/chunk/leveldb_23.py +10 -10
  112. amulet/level/formats/leveldb_world/interface/chunk/leveldb_24.py +10 -10
  113. amulet/level/formats/leveldb_world/interface/chunk/leveldb_25.py +24 -24
  114. amulet/level/formats/leveldb_world/interface/chunk/leveldb_26.py +10 -10
  115. amulet/level/formats/leveldb_world/interface/chunk/leveldb_27.py +10 -10
  116. amulet/level/formats/leveldb_world/interface/chunk/leveldb_28.py +10 -10
  117. amulet/level/formats/leveldb_world/interface/chunk/leveldb_29.py +33 -33
  118. amulet/level/formats/leveldb_world/interface/chunk/leveldb_3.py +57 -57
  119. amulet/level/formats/leveldb_world/interface/chunk/leveldb_30.py +10 -10
  120. amulet/level/formats/leveldb_world/interface/chunk/leveldb_31.py +10 -10
  121. amulet/level/formats/leveldb_world/interface/chunk/leveldb_32.py +10 -10
  122. amulet/level/formats/leveldb_world/interface/chunk/leveldb_33.py +10 -10
  123. amulet/level/formats/leveldb_world/interface/chunk/leveldb_34.py +10 -10
  124. amulet/level/formats/leveldb_world/interface/chunk/leveldb_35.py +10 -10
  125. amulet/level/formats/leveldb_world/interface/chunk/leveldb_36.py +10 -10
  126. amulet/level/formats/leveldb_world/interface/chunk/leveldb_37.py +10 -10
  127. amulet/level/formats/leveldb_world/interface/chunk/leveldb_38.py +10 -10
  128. amulet/level/formats/leveldb_world/interface/chunk/leveldb_39.py +12 -12
  129. amulet/level/formats/leveldb_world/interface/chunk/leveldb_4.py +12 -12
  130. amulet/level/formats/leveldb_world/interface/chunk/leveldb_40.py +16 -16
  131. amulet/level/formats/leveldb_world/interface/chunk/leveldb_5.py +12 -12
  132. amulet/level/formats/leveldb_world/interface/chunk/leveldb_6.py +12 -12
  133. amulet/level/formats/leveldb_world/interface/chunk/leveldb_7.py +12 -12
  134. amulet/level/formats/leveldb_world/interface/chunk/leveldb_8.py +180 -180
  135. amulet/level/formats/leveldb_world/interface/chunk/leveldb_9.py +18 -18
  136. amulet/level/formats/leveldb_world/interface/chunk/leveldb_chunk_versions.py +79 -79
  137. amulet/level/formats/mcstructure/__init__.py +3 -3
  138. amulet/level/formats/mcstructure/chunk.py +50 -50
  139. amulet/level/formats/mcstructure/format_wrapper.py +408 -408
  140. amulet/level/formats/mcstructure/interface.py +175 -175
  141. amulet/level/formats/schematic/__init__.py +3 -3
  142. amulet/level/formats/schematic/chunk.py +55 -55
  143. amulet/level/formats/schematic/data_types.py +4 -4
  144. amulet/level/formats/schematic/format_wrapper.py +373 -373
  145. amulet/level/formats/schematic/interface.py +142 -142
  146. amulet/level/formats/sponge_schem/__init__.py +4 -4
  147. amulet/level/formats/sponge_schem/chunk.py +62 -62
  148. amulet/level/formats/sponge_schem/format_wrapper.py +463 -463
  149. amulet/level/formats/sponge_schem/interface.py +118 -118
  150. amulet/level/formats/sponge_schem/varint/__init__.py +1 -1
  151. amulet/level/formats/sponge_schem/varint/varint.py +87 -87
  152. amulet/level/interfaces/chunk/anvil/anvil_0.py +72 -72
  153. amulet/level/interfaces/chunk/anvil/anvil_1444.py +336 -336
  154. amulet/level/interfaces/chunk/anvil/anvil_1466.py +94 -94
  155. amulet/level/interfaces/chunk/anvil/anvil_1467.py +37 -37
  156. amulet/level/interfaces/chunk/anvil/anvil_1484.py +20 -20
  157. amulet/level/interfaces/chunk/anvil/anvil_1503.py +20 -20
  158. amulet/level/interfaces/chunk/anvil/anvil_1519.py +34 -34
  159. amulet/level/interfaces/chunk/anvil/anvil_1901.py +20 -20
  160. amulet/level/interfaces/chunk/anvil/anvil_1908.py +20 -20
  161. amulet/level/interfaces/chunk/anvil/anvil_1912.py +21 -21
  162. amulet/level/interfaces/chunk/anvil/anvil_1934.py +20 -20
  163. amulet/level/interfaces/chunk/anvil/anvil_2203.py +69 -69
  164. amulet/level/interfaces/chunk/anvil/anvil_2529.py +19 -19
  165. amulet/level/interfaces/chunk/anvil/anvil_2681.py +76 -76
  166. amulet/level/interfaces/chunk/anvil/anvil_2709.py +19 -19
  167. amulet/level/interfaces/chunk/anvil/anvil_2844.py +267 -267
  168. amulet/level/interfaces/chunk/anvil/anvil_3463.py +19 -19
  169. amulet/level/interfaces/chunk/anvil/anvil_na.py +607 -607
  170. amulet/level/interfaces/chunk/anvil/base_anvil_interface.py +326 -326
  171. amulet/level/load.py +59 -59
  172. amulet/level/loader.py +95 -95
  173. amulet/level/translators/chunk/bedrock/__init__.py +267 -267
  174. amulet/level/translators/chunk/bedrock/bedrock_nbt_blockstate_translator.py +46 -46
  175. amulet/level/translators/chunk/bedrock/bedrock_numerical_translator.py +39 -39
  176. amulet/level/translators/chunk/bedrock/bedrock_psudo_numerical_translator.py +37 -37
  177. amulet/level/translators/chunk/java/java_1_18_translator.py +40 -40
  178. amulet/level/translators/chunk/java/java_blockstate_translator.py +94 -94
  179. amulet/level/translators/chunk/java/java_numerical_translator.py +62 -62
  180. amulet/libs/leveldb/__init__.py +7 -7
  181. amulet/operations/__init__.py +5 -5
  182. amulet/operations/clone.py +18 -18
  183. amulet/operations/delete_chunk.py +32 -32
  184. amulet/operations/fill.py +30 -30
  185. amulet/operations/paste.py +65 -65
  186. amulet/operations/replace.py +58 -58
  187. amulet/utils/__init__.py +14 -14
  188. amulet/utils/format_utils.py +41 -41
  189. amulet/utils/generator.py +15 -15
  190. amulet/utils/matrix.py +243 -243
  191. amulet/utils/numpy_helpers.py +46 -46
  192. amulet/utils/world_utils.py +349 -349
  193. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/METADATA +97 -97
  194. amulet_core-1.9.20.dist-info/RECORD +208 -0
  195. amulet_core-1.9.19.dist-info/RECORD +0 -208
  196. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/WHEEL +0 -0
  197. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/entry_points.txt +0 -0
  198. {amulet_core-1.9.19.dist-info → amulet_core-1.9.20.dist-info}/top_level.txt +0 -0
@@ -1,118 +1,118 @@
1
- from typing import TYPE_CHECKING, Any, Tuple
2
- import numpy
3
-
4
- from amulet.api.wrapper import Interface, EntityIDType, EntityCoordType
5
- from amulet.api.chunk import Chunk
6
- from amulet.api.selection import SelectionBox
7
- from amulet.api.data_types import AnyNDArray, VersionIdentifierType, VersionNumberAny
8
- from amulet.level.loader import Translators
9
- from amulet.api.block import Block
10
- from .chunk import SpongeSchemChunk
11
-
12
- from amulet_nbt import NamedTag
13
-
14
- if TYPE_CHECKING:
15
- from amulet.api.wrapper import Translator
16
- from PyMCTranslate import TranslationManager
17
-
18
-
19
- class SpongeSchemInterface(Interface):
20
- _entity_id_type = EntityIDType.namespace_str_Id
21
- _entity_coord_type = EntityCoordType.Pos_list_double
22
- _block_entity_id_type = EntityIDType.namespace_str_Id
23
- _block_entity_coord_type = EntityCoordType.Pos_array_int
24
-
25
- def is_valid(self, key: Tuple) -> bool:
26
- return True
27
-
28
- def decode(
29
- self, cx: int, cz: int, data: SpongeSchemChunk
30
- ) -> Tuple["Chunk", AnyNDArray]:
31
- """
32
- Create an amulet.api.chunk.Chunk object from raw data given by the format
33
- :param cx: chunk x coordinate
34
- :param cz: chunk z coordinate
35
- :param data: Raw chunk data provided by the format.
36
- :return: Chunk object in version-specific format, along with the block_palette for that chunk.
37
- """
38
- palette = numpy.empty(len(data.palette) + 1, dtype=object)
39
- palette[0] = Block(namespace="minecraft", base_name="air")
40
- palette[1:] = data.palette[:]
41
-
42
- chunk = Chunk(cx, cz)
43
- box = data.selection.create_moved_box((cx * 16, 0, cz * 16), subtract=True)
44
- chunk.blocks[box.slice] = data.blocks + 1
45
- for tag in data.block_entities:
46
- block_entity = self._decode_block_entity(
47
- NamedTag(tag), self._block_entity_id_type, self._block_entity_coord_type
48
- )
49
- if block_entity is not None:
50
- chunk.block_entities.insert(block_entity)
51
- for tag in data.entities:
52
- entity = self._decode_entity(
53
- NamedTag(tag), self._block_entity_id_type, self._block_entity_coord_type
54
- )
55
- if entity is not None:
56
- chunk.entities.append(entity)
57
-
58
- return chunk, palette
59
-
60
- def encode(
61
- self,
62
- chunk: "Chunk",
63
- palette: AnyNDArray,
64
- max_world_version: VersionIdentifierType,
65
- box: SelectionBox,
66
- ) -> SpongeSchemChunk:
67
- """
68
- Take a version-specific chunk and encode it to raw data for the format to store.
69
- :param chunk: The already translated version-specfic chunk to encode.
70
- :param palette: The block_palette the ids in the chunk correspond to.
71
- :type palette: numpy.ndarray[Block]
72
- :param max_world_version: The key to use to find the encoder.
73
- :param box: The volume of the chunk to pack.
74
- :return: Raw data to be stored by the Format.
75
- """
76
- entities = []
77
- for entity in chunk.entities:
78
- if entity.location in box:
79
- entities.append(
80
- self._encode_entity(
81
- entity, self._entity_id_type, self._entity_coord_type
82
- ).compound
83
- )
84
- block_entities = []
85
- for block_entity in chunk.block_entities:
86
- if block_entity.location in box:
87
- block_entities.append(
88
- self._encode_block_entity(
89
- block_entity,
90
- self._block_entity_id_type,
91
- self._block_entity_coord_type,
92
- ).compound
93
- )
94
-
95
- slices = box.create_moved_box(
96
- (chunk.cx * 16, 0, chunk.cz * 16), subtract=True
97
- ).slice
98
-
99
- return SpongeSchemChunk(
100
- box,
101
- numpy.asarray(chunk.blocks[slices]),
102
- palette.copy(),
103
- block_entities,
104
- entities,
105
- )
106
-
107
- def get_translator(
108
- self,
109
- max_world_version: Tuple[str, int],
110
- data: Any = None,
111
- translation_manager: "TranslationManager" = None,
112
- ) -> Tuple["Translator", VersionNumberAny]:
113
- platform, version_number = max_world_version
114
- if platform != "java":
115
- raise ValueError("Platform must be java")
116
- version = translation_manager.get_version(platform, version_number)
117
- version_number = version.data_version
118
- return Translators.get((platform, version_number)), version_number
1
+ from typing import TYPE_CHECKING, Any, Tuple
2
+ import numpy
3
+
4
+ from amulet.api.wrapper import Interface, EntityIDType, EntityCoordType
5
+ from amulet.api.chunk import Chunk
6
+ from amulet.api.selection import SelectionBox
7
+ from amulet.api.data_types import AnyNDArray, VersionIdentifierType, VersionNumberAny
8
+ from amulet.level.loader import Translators
9
+ from amulet.api.block import Block
10
+ from .chunk import SpongeSchemChunk
11
+
12
+ from amulet_nbt import NamedTag
13
+
14
+ if TYPE_CHECKING:
15
+ from amulet.api.wrapper import Translator
16
+ from PyMCTranslate import TranslationManager
17
+
18
+
19
+ class SpongeSchemInterface(Interface):
20
+ _entity_id_type = EntityIDType.namespace_str_Id
21
+ _entity_coord_type = EntityCoordType.Pos_list_double
22
+ _block_entity_id_type = EntityIDType.namespace_str_Id
23
+ _block_entity_coord_type = EntityCoordType.Pos_array_int
24
+
25
+ def is_valid(self, key: Tuple) -> bool:
26
+ return True
27
+
28
+ def decode(
29
+ self, cx: int, cz: int, data: SpongeSchemChunk
30
+ ) -> Tuple["Chunk", AnyNDArray]:
31
+ """
32
+ Create an amulet.api.chunk.Chunk object from raw data given by the format
33
+ :param cx: chunk x coordinate
34
+ :param cz: chunk z coordinate
35
+ :param data: Raw chunk data provided by the format.
36
+ :return: Chunk object in version-specific format, along with the block_palette for that chunk.
37
+ """
38
+ palette = numpy.empty(len(data.palette) + 1, dtype=object)
39
+ palette[0] = Block(namespace="minecraft", base_name="air")
40
+ palette[1:] = data.palette[:]
41
+
42
+ chunk = Chunk(cx, cz)
43
+ box = data.selection.create_moved_box((cx * 16, 0, cz * 16), subtract=True)
44
+ chunk.blocks[box.slice] = data.blocks + 1
45
+ for tag in data.block_entities:
46
+ block_entity = self._decode_block_entity(
47
+ NamedTag(tag), self._block_entity_id_type, self._block_entity_coord_type
48
+ )
49
+ if block_entity is not None:
50
+ chunk.block_entities.insert(block_entity)
51
+ for tag in data.entities:
52
+ entity = self._decode_entity(
53
+ NamedTag(tag), self._block_entity_id_type, self._block_entity_coord_type
54
+ )
55
+ if entity is not None:
56
+ chunk.entities.append(entity)
57
+
58
+ return chunk, palette
59
+
60
+ def encode(
61
+ self,
62
+ chunk: "Chunk",
63
+ palette: AnyNDArray,
64
+ max_world_version: VersionIdentifierType,
65
+ box: SelectionBox,
66
+ ) -> SpongeSchemChunk:
67
+ """
68
+ Take a version-specific chunk and encode it to raw data for the format to store.
69
+ :param chunk: The already translated version-specfic chunk to encode.
70
+ :param palette: The block_palette the ids in the chunk correspond to.
71
+ :type palette: numpy.ndarray[Block]
72
+ :param max_world_version: The key to use to find the encoder.
73
+ :param box: The volume of the chunk to pack.
74
+ :return: Raw data to be stored by the Format.
75
+ """
76
+ entities = []
77
+ for entity in chunk.entities:
78
+ if entity.location in box:
79
+ entities.append(
80
+ self._encode_entity(
81
+ entity, self._entity_id_type, self._entity_coord_type
82
+ ).compound
83
+ )
84
+ block_entities = []
85
+ for block_entity in chunk.block_entities:
86
+ if block_entity.location in box:
87
+ block_entities.append(
88
+ self._encode_block_entity(
89
+ block_entity,
90
+ self._block_entity_id_type,
91
+ self._block_entity_coord_type,
92
+ ).compound
93
+ )
94
+
95
+ slices = box.create_moved_box(
96
+ (chunk.cx * 16, 0, chunk.cz * 16), subtract=True
97
+ ).slice
98
+
99
+ return SpongeSchemChunk(
100
+ box,
101
+ numpy.asarray(chunk.blocks[slices]),
102
+ palette.copy(),
103
+ block_entities,
104
+ entities,
105
+ )
106
+
107
+ def get_translator(
108
+ self,
109
+ max_world_version: Tuple[str, int],
110
+ data: Any = None,
111
+ translation_manager: "TranslationManager" = None,
112
+ ) -> Tuple["Translator", VersionNumberAny]:
113
+ platform, version_number = max_world_version
114
+ if platform != "java":
115
+ raise ValueError("Platform must be java")
116
+ version = translation_manager.get_version(platform, version_number)
117
+ version_number = version.data_version
118
+ return Translators.get((platform, version_number)), version_number
@@ -1 +1 @@
1
- from .varint import decode_stream, decode_bytes, decode_byte_array, encode_array
1
+ from .varint import decode_stream, decode_bytes, decode_byte_array, encode_array
@@ -1,87 +1,87 @@
1
- """Varint encoder/decoder
2
-
3
- varints are a common encoding for variable length integer data, used in
4
- libraries such as sqlite, protobuf, v8, and more.
5
-
6
- Here's a quick and dirty module to help avoid reimplementing the same thing
7
- over and over again.
8
-
9
- With modifications to allow reading and writing an array of varints.
10
- """
11
-
12
- from io import BytesIO
13
- from typing import List, Iterable
14
-
15
-
16
- def _read_byte(stream: BytesIO) -> int:
17
- """Read a byte from the file (as an integer)
18
-
19
- :param stream: The stream to read the byte from.
20
- :return: The integer value of the byte.
21
- :raises:
22
- EOFError: if the stream ends while reading bytes.
23
- """
24
- c = stream.read(1)
25
- if not c:
26
- raise EOFError("Unexpected EOF while reading bytes")
27
- return ord(c)
28
-
29
-
30
- def decode_stream_one(stream: BytesIO) -> int:
31
- """Read a varint from `stream`"""
32
- shift = 0
33
- result = 0
34
- while True:
35
- i = _read_byte(stream)
36
- result |= (i & 0x7F) << shift
37
- shift += 7
38
- if not (i & 0x80):
39
- break
40
- return result
41
-
42
-
43
- def decode_bytes_one(buf: bytes):
44
- """Read a varint from `buf` bytes"""
45
- return decode_stream_one(BytesIO(buf))
46
-
47
-
48
- def decode_stream(stream: BytesIO) -> List[int]:
49
- """Read varint(s) from `stream` until the stream has been exhausted."""
50
- start = stream.tell()
51
- end = stream.seek(0, 2)
52
- stream.seek(start)
53
-
54
- result = []
55
- while stream.tell() < end:
56
- result.append(decode_stream_one(stream))
57
- return result
58
-
59
-
60
- def decode_bytes(buf: bytes) -> List[int]:
61
- """Read varint(s) from `buf` bytes until all the bytes have been exhausted."""
62
- return decode_stream(BytesIO(buf))
63
-
64
-
65
- def decode_byte_array(buf: Iterable[int]) -> List[int]:
66
- """Read varint(s) from an iterable of ints until the iterable has been exhausted.
67
- All ints must be in range(0, 256)"""
68
- return decode_bytes(bytes(buf))
69
-
70
-
71
- def encode(number: int):
72
- """Pack `number` into varint bytes"""
73
- buf = []
74
- while True:
75
- towrite = number & 0x7F
76
- number >>= 7
77
- if number:
78
- buf.append(bytes((towrite | 0x80,)))
79
- else:
80
- buf.append(bytes((towrite,)))
81
- break
82
- return b"".join(buf)
83
-
84
-
85
- def encode_array(array: Iterable[int]) -> bytes:
86
- """Pack an array of integers into a sequence of packed varint(s)."""
87
- return b"".join(encode(n) for n in array)
1
+ """Varint encoder/decoder
2
+
3
+ varints are a common encoding for variable length integer data, used in
4
+ libraries such as sqlite, protobuf, v8, and more.
5
+
6
+ Here's a quick and dirty module to help avoid reimplementing the same thing
7
+ over and over again.
8
+
9
+ With modifications to allow reading and writing an array of varints.
10
+ """
11
+
12
+ from io import BytesIO
13
+ from typing import List, Iterable
14
+
15
+
16
+ def _read_byte(stream: BytesIO) -> int:
17
+ """Read a byte from the file (as an integer)
18
+
19
+ :param stream: The stream to read the byte from.
20
+ :return: The integer value of the byte.
21
+ :raises:
22
+ EOFError: if the stream ends while reading bytes.
23
+ """
24
+ c = stream.read(1)
25
+ if not c:
26
+ raise EOFError("Unexpected EOF while reading bytes")
27
+ return ord(c)
28
+
29
+
30
+ def decode_stream_one(stream: BytesIO) -> int:
31
+ """Read a varint from `stream`"""
32
+ shift = 0
33
+ result = 0
34
+ while True:
35
+ i = _read_byte(stream)
36
+ result |= (i & 0x7F) << shift
37
+ shift += 7
38
+ if not (i & 0x80):
39
+ break
40
+ return result
41
+
42
+
43
+ def decode_bytes_one(buf: bytes):
44
+ """Read a varint from `buf` bytes"""
45
+ return decode_stream_one(BytesIO(buf))
46
+
47
+
48
+ def decode_stream(stream: BytesIO) -> List[int]:
49
+ """Read varint(s) from `stream` until the stream has been exhausted."""
50
+ start = stream.tell()
51
+ end = stream.seek(0, 2)
52
+ stream.seek(start)
53
+
54
+ result = []
55
+ while stream.tell() < end:
56
+ result.append(decode_stream_one(stream))
57
+ return result
58
+
59
+
60
+ def decode_bytes(buf: bytes) -> List[int]:
61
+ """Read varint(s) from `buf` bytes until all the bytes have been exhausted."""
62
+ return decode_stream(BytesIO(buf))
63
+
64
+
65
+ def decode_byte_array(buf: Iterable[int]) -> List[int]:
66
+ """Read varint(s) from an iterable of ints until the iterable has been exhausted.
67
+ All ints must be in range(0, 256)"""
68
+ return decode_bytes(bytes(buf))
69
+
70
+
71
+ def encode(number: int):
72
+ """Pack `number` into varint bytes"""
73
+ buf = []
74
+ while True:
75
+ towrite = number & 0x7F
76
+ number >>= 7
77
+ if number:
78
+ buf.append(bytes((towrite | 0x80,)))
79
+ else:
80
+ buf.append(bytes((towrite,)))
81
+ break
82
+ return b"".join(buf)
83
+
84
+
85
+ def encode_array(array: Iterable[int]) -> bytes:
86
+ """Pack an array of integers into a sequence of packed varint(s)."""
87
+ return b"".join(encode(n) for n in array)
@@ -1,72 +1,72 @@
1
- from __future__ import annotations
2
-
3
- from typing import Tuple, TYPE_CHECKING
4
-
5
- from amulet_nbt import IntTag
6
-
7
- import amulet
8
- from .base_anvil_interface import ChunkPathType, ChunkDataType
9
- from .anvil_na import AnvilNAInterface as ParentInterface
10
-
11
- if TYPE_CHECKING:
12
- from amulet.api.chunk import Chunk
13
-
14
-
15
- class Anvil0Interface(ParentInterface):
16
- """
17
- Added the DataVersion tag
18
- Note that this has not been tested before 1.12
19
- """
20
-
21
- V = None
22
- RegionDataVersion: ChunkPathType = (
23
- "region",
24
- [("DataVersion", IntTag)],
25
- IntTag,
26
- )
27
-
28
- def __init__(self):
29
- super().__init__()
30
- self._unregister_decoder(self._decode_v_tag)
31
- self._unregister_encoder(self._encode_v_tag)
32
-
33
- self._register_post_decoder(self._post_decode_data_version)
34
-
35
- @staticmethod
36
- def minor_is_valid(key: int):
37
- return 0 <= key < 1444
38
-
39
- def _post_decode_data_version(
40
- self, chunk: Chunk, data: ChunkDataType, floor_cy: int, height_cy: int
41
- ):
42
- # all versioned data must get removed from data
43
- self.get_layer_obj(data, self.RegionDataVersion, pop_last=True)
44
-
45
- def _decode_entities(
46
- self, chunk: Chunk, data: ChunkDataType, floor_cy: int, height_cy: int
47
- ):
48
- ents = self._decode_entity_list(
49
- self.get_layer_obj(data, self.Entities, pop_last=True)
50
- )
51
- if amulet.entity_support:
52
- chunk.entities = ents
53
- else:
54
- chunk._native_entities.extend(ents)
55
- chunk._native_version = (
56
- "java",
57
- self.get_layer_obj(data, self.RegionDataVersion).py_int,
58
- )
59
-
60
- def _init_encode(
61
- self,
62
- chunk: Chunk,
63
- max_world_version: Tuple[str, int],
64
- floor_cy: int,
65
- height_cy: int,
66
- ) -> ChunkDataType:
67
- data = super()._init_encode(chunk, max_world_version, floor_cy, height_cy)
68
- self.set_layer_obj(data, self.RegionDataVersion, IntTag(max_world_version[1]))
69
- return data
70
-
71
-
72
- export = Anvil0Interface
1
+ from __future__ import annotations
2
+
3
+ from typing import Tuple, TYPE_CHECKING
4
+
5
+ from amulet_nbt import IntTag
6
+
7
+ import amulet
8
+ from .base_anvil_interface import ChunkPathType, ChunkDataType
9
+ from .anvil_na import AnvilNAInterface as ParentInterface
10
+
11
+ if TYPE_CHECKING:
12
+ from amulet.api.chunk import Chunk
13
+
14
+
15
+ class Anvil0Interface(ParentInterface):
16
+ """
17
+ Added the DataVersion tag
18
+ Note that this has not been tested before 1.12
19
+ """
20
+
21
+ V = None
22
+ RegionDataVersion: ChunkPathType = (
23
+ "region",
24
+ [("DataVersion", IntTag)],
25
+ IntTag,
26
+ )
27
+
28
+ def __init__(self):
29
+ super().__init__()
30
+ self._unregister_decoder(self._decode_v_tag)
31
+ self._unregister_encoder(self._encode_v_tag)
32
+
33
+ self._register_post_decoder(self._post_decode_data_version)
34
+
35
+ @staticmethod
36
+ def minor_is_valid(key: int):
37
+ return 0 <= key < 1444
38
+
39
+ def _post_decode_data_version(
40
+ self, chunk: Chunk, data: ChunkDataType, floor_cy: int, height_cy: int
41
+ ):
42
+ # all versioned data must get removed from data
43
+ self.get_layer_obj(data, self.RegionDataVersion, pop_last=True)
44
+
45
+ def _decode_entities(
46
+ self, chunk: Chunk, data: ChunkDataType, floor_cy: int, height_cy: int
47
+ ):
48
+ ents = self._decode_entity_list(
49
+ self.get_layer_obj(data, self.Entities, pop_last=True)
50
+ )
51
+ if amulet.entity_support:
52
+ chunk.entities = ents
53
+ else:
54
+ chunk._native_entities.extend(ents)
55
+ chunk._native_version = (
56
+ "java",
57
+ self.get_layer_obj(data, self.RegionDataVersion).py_int,
58
+ )
59
+
60
+ def _init_encode(
61
+ self,
62
+ chunk: Chunk,
63
+ max_world_version: Tuple[str, int],
64
+ floor_cy: int,
65
+ height_cy: int,
66
+ ) -> ChunkDataType:
67
+ data = super()._init_encode(chunk, max_world_version, floor_cy, height_cy)
68
+ self.set_layer_obj(data, self.RegionDataVersion, IntTag(max_world_version[1]))
69
+ return data
70
+
71
+
72
+ export = Anvil0Interface