amulet-core 2.0a7__cp311-cp311-win_amd64.whl → 2.0.1.0.1297307203.19.43.34808.0a0__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.
- amulet/core/__init__.py +36 -0
- amulet/core/__pyinstaller/hook-amulet.core.py +4 -0
- amulet/core/_amulet_core.cp311-win_amd64.pyd +0 -0
- amulet/core/_amulet_core.pyi +7 -0
- amulet/{_version.py → core/_version.py} +3 -3
- amulet/core/amulet_core.dll +0 -0
- amulet/core/amulet_core.lib +0 -0
- amulet/core/amulet_coreConfig.cmake +18 -0
- amulet/{biome.pyi → core/biome/__init__.pyi} +3 -3
- amulet/core/biome/biome.hpp +53 -0
- amulet/{block.pyi → core/block/__init__.pyi} +25 -26
- amulet/core/block/block.hpp +156 -0
- amulet/{block_entity.pyi → core/block_entity/__init__.pyi} +7 -7
- amulet/core/block_entity/block_entity.hpp +84 -0
- amulet/{errors.py → core/chunk/__init__.pyi} +37 -33
- amulet/core/chunk/chunk.hpp +126 -0
- amulet/core/chunk/component/__init__.pyi +18 -0
- amulet/core/chunk/component/biome_3d_component.hpp +96 -0
- amulet/core/chunk/component/block_component.hpp +101 -0
- amulet/core/chunk/component/block_component.pyi +28 -0
- amulet/core/chunk/component/block_entity_component.hpp +119 -0
- amulet/core/chunk/component/section_array_map.hpp +129 -0
- amulet/{chunk_components.pyi → core/chunk/component/section_array_map.pyi} +4 -24
- amulet/core/dll.hpp +21 -0
- amulet/core/entity/__init__.pyi +105 -0
- amulet/core/entity/entity.hpp +100 -0
- amulet/{palette → core/palette}/__init__.pyi +2 -2
- amulet/core/palette/biome_palette.hpp +65 -0
- amulet/{palette → core/palette}/biome_palette.pyi +8 -8
- amulet/core/palette/block_palette.hpp +71 -0
- amulet/{palette → core/palette}/block_palette.pyi +12 -10
- amulet/core/selection/__init__.pyi +8 -0
- amulet/core/selection/box.hpp +86 -0
- amulet/core/selection/box.pyi +215 -0
- amulet/core/selection/group.hpp +80 -0
- amulet/core/selection/group.pyi +213 -0
- amulet/{version.pyi → core/version/__init__.pyi} +58 -10
- amulet/core/version/version.hpp +204 -0
- {amulet_core-2.0a7.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/METADATA +25 -20
- amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info/RECORD +45 -0
- {amulet_core-2.0a7.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/WHEEL +1 -1
- amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info/entry_points.txt +2 -0
- amulet/__init__.cp311-win_amd64.pyd +0 -0
- amulet/__init__.py.cpp +0 -43
- amulet/__init__.pyi +0 -28
- amulet/__pyinstaller/hook-amulet.py +0 -4
- amulet/_init.py +0 -26
- amulet/biome.cpp +0 -36
- amulet/biome.hpp +0 -43
- amulet/biome.py.cpp +0 -122
- amulet/block.cpp +0 -435
- amulet/block.hpp +0 -119
- amulet/block.py.cpp +0 -377
- amulet/block_entity.cpp +0 -12
- amulet/block_entity.hpp +0 -56
- amulet/block_entity.py.cpp +0 -115
- amulet/chunk.cpp +0 -16
- amulet/chunk.hpp +0 -99
- amulet/chunk.py.cpp +0 -80
- amulet/chunk.pyi +0 -28
- amulet/chunk_components/biome_3d_component.cpp +0 -5
- amulet/chunk_components/biome_3d_component.hpp +0 -79
- amulet/chunk_components/block_component.cpp +0 -41
- amulet/chunk_components/block_component.hpp +0 -88
- amulet/chunk_components/block_entity_component.cpp +0 -5
- amulet/chunk_components/block_entity_component.hpp +0 -147
- amulet/chunk_components/section_array_map.cpp +0 -129
- amulet/chunk_components/section_array_map.hpp +0 -147
- amulet/collections/eq.py.hpp +0 -37
- amulet/collections/hash.py.hpp +0 -27
- amulet/collections/holder.py.hpp +0 -37
- amulet/collections/iterator.py.hpp +0 -80
- amulet/collections/mapping.py.hpp +0 -199
- amulet/collections/mutable_mapping.py.hpp +0 -226
- amulet/collections/sequence.py.hpp +0 -163
- amulet/collections.pyi +0 -40
- amulet/data_types.py +0 -29
- amulet/entity.py +0 -182
- amulet/game/__init__.py +0 -7
- amulet/game/_game.py +0 -152
- amulet/game/_universal/__init__.py +0 -1
- amulet/game/_universal/_biome.py +0 -17
- amulet/game/_universal/_block.py +0 -47
- amulet/game/_universal/_version.py +0 -68
- amulet/game/abc/__init__.py +0 -22
- amulet/game/abc/_block_specification.py +0 -150
- amulet/game/abc/biome.py +0 -213
- amulet/game/abc/block.py +0 -331
- amulet/game/abc/game_version_container.py +0 -25
- amulet/game/abc/json_interface.py +0 -27
- amulet/game/abc/version.py +0 -44
- amulet/game/bedrock/__init__.py +0 -1
- amulet/game/bedrock/_biome.py +0 -35
- amulet/game/bedrock/_block.py +0 -42
- amulet/game/bedrock/_version.py +0 -165
- amulet/game/java/__init__.py +0 -2
- amulet/game/java/_biome.py +0 -35
- amulet/game/java/_block.py +0 -60
- amulet/game/java/_version.py +0 -176
- amulet/game/translate/__init__.py +0 -12
- amulet/game/translate/_functions/__init__.py +0 -15
- amulet/game/translate/_functions/_code_functions/__init__.py +0 -0
- amulet/game/translate/_functions/_code_functions/_text.py +0 -553
- amulet/game/translate/_functions/_code_functions/banner_pattern.py +0 -67
- amulet/game/translate/_functions/_code_functions/bedrock_chest_connection.py +0 -152
- amulet/game/translate/_functions/_code_functions/bedrock_moving_block_pos.py +0 -88
- amulet/game/translate/_functions/_code_functions/bedrock_sign.py +0 -152
- amulet/game/translate/_functions/_code_functions/bedrock_skull_rotation.py +0 -16
- amulet/game/translate/_functions/_code_functions/custom_name.py +0 -146
- amulet/game/translate/_functions/_frozen.py +0 -66
- amulet/game/translate/_functions/_state.py +0 -54
- amulet/game/translate/_functions/_typing.py +0 -98
- amulet/game/translate/_functions/abc.py +0 -123
- amulet/game/translate/_functions/carry_nbt.py +0 -160
- amulet/game/translate/_functions/carry_properties.py +0 -80
- amulet/game/translate/_functions/code.py +0 -143
- amulet/game/translate/_functions/map_block_name.py +0 -66
- amulet/game/translate/_functions/map_nbt.py +0 -111
- amulet/game/translate/_functions/map_properties.py +0 -93
- amulet/game/translate/_functions/multiblock.py +0 -112
- amulet/game/translate/_functions/new_block.py +0 -42
- amulet/game/translate/_functions/new_entity.py +0 -43
- amulet/game/translate/_functions/new_nbt.py +0 -206
- amulet/game/translate/_functions/new_properties.py +0 -64
- amulet/game/translate/_functions/sequence.py +0 -51
- amulet/game/translate/_functions/walk_input_nbt.py +0 -331
- amulet/game/translate/_translator.py +0 -433
- amulet/img/__init__.py +0 -10
- amulet/img/missing_no.png +0 -0
- amulet/img/missing_pack.png +0 -0
- amulet/img/missing_world.png +0 -0
- amulet/io/binary_reader.hpp +0 -45
- amulet/io/binary_writer.hpp +0 -30
- amulet/item.py +0 -75
- amulet/level/__init__.pyi +0 -23
- amulet/level/_load.py +0 -100
- amulet/level/abc/__init__.py +0 -12
- amulet/level/abc/_chunk_handle.py +0 -335
- amulet/level/abc/_dimension.py +0 -86
- amulet/level/abc/_history/__init__.py +0 -1
- amulet/level/abc/_history/_cache.py +0 -224
- amulet/level/abc/_history/_history_manager.py +0 -291
- amulet/level/abc/_level/__init__.py +0 -5
- amulet/level/abc/_level/_compactable_level.py +0 -10
- amulet/level/abc/_level/_creatable_level.py +0 -28
- amulet/level/abc/_level/_disk_level.py +0 -17
- amulet/level/abc/_level/_level.py +0 -449
- amulet/level/abc/_level/_loadable_level.py +0 -42
- amulet/level/abc/_player_storage.py +0 -7
- amulet/level/abc/_raw_level.py +0 -187
- amulet/level/abc/_registry.py +0 -40
- amulet/level/java/__init__.pyi +0 -16
- amulet/level/java/_chunk_handle.py +0 -17
- amulet/level/java/_dimension.py +0 -20
- amulet/level/java/_level.py +0 -184
- amulet/level/java/_raw/__init__.pyi +0 -15
- amulet/level/java/_raw/_chunk.pyi +0 -23
- amulet/level/java/_raw/_constant.py +0 -9
- amulet/level/java/_raw/_data_pack/__init__.py +0 -2
- amulet/level/java/_raw/_data_pack/data_pack.py +0 -241
- amulet/level/java/_raw/_data_pack/data_pack_manager.py +0 -77
- amulet/level/java/_raw/_dimension.py +0 -86
- amulet/level/java/_raw/_level.py +0 -507
- amulet/level/java/_raw/_typing.py +0 -3
- amulet/level/java/_raw/java_chunk_decode.cpp +0 -531
- amulet/level/java/_raw/java_chunk_decode.hpp +0 -23
- amulet/level/java/_raw/java_chunk_encode.cpp +0 -25
- amulet/level/java/_raw/java_chunk_encode.hpp +0 -23
- amulet/level/java/anvil/__init__.py +0 -2
- amulet/level/java/anvil/_dimension.py +0 -170
- amulet/level/java/anvil/_region.py +0 -421
- amulet/level/java/anvil/_sector_manager.py +0 -223
- amulet/level/java/chunk.pyi +0 -81
- amulet/level/java/chunk_/_chunk.py +0 -260
- amulet/level/java/chunk_/components/inhabited_time.py +0 -12
- amulet/level/java/chunk_/components/last_update.py +0 -12
- amulet/level/java/chunk_/components/legacy_version.py +0 -12
- amulet/level/java/chunk_/components/light_populated.py +0 -12
- amulet/level/java/chunk_/components/named_height_2d.py +0 -37
- amulet/level/java/chunk_/components/status.py +0 -11
- amulet/level/java/chunk_/components/terrain_populated.py +0 -12
- amulet/level/java/chunk_components/data_version_component.cpp +0 -32
- amulet/level/java/chunk_components/data_version_component.hpp +0 -31
- amulet/level/java/chunk_components/java_raw_chunk_component.cpp +0 -56
- amulet/level/java/chunk_components/java_raw_chunk_component.hpp +0 -45
- amulet/level/java/chunk_components.pyi +0 -22
- amulet/level/java/java_chunk.cpp +0 -170
- amulet/level/java/java_chunk.hpp +0 -141
- amulet/level/java/long_array.hpp +0 -175
- amulet/level/java/long_array.pyi +0 -39
- amulet/level/temporary_level/__init__.py +0 -1
- amulet/level/temporary_level/_level.py +0 -16
- amulet/mesh/__init__.py +0 -0
- amulet/mesh/block/__init__.py +0 -1
- amulet/mesh/block/block_mesh.py +0 -369
- amulet/mesh/block/cube.py +0 -149
- amulet/mesh/block/missing_block.py +0 -20
- amulet/mesh/util.py +0 -17
- amulet/palette/biome_palette.hpp +0 -85
- amulet/palette/block_palette.cpp +0 -32
- amulet/palette/block_palette.hpp +0 -93
- amulet/player.py +0 -62
- amulet/pybind11/collections.hpp +0 -118
- amulet/pybind11/numpy.hpp +0 -26
- amulet/pybind11/py_module.hpp +0 -34
- amulet/pybind11/type_hints.hpp +0 -51
- amulet/pybind11/types.hpp +0 -25
- amulet/pybind11/typing.hpp +0 -7
- amulet/resource_pack/__init__.py +0 -62
- amulet/resource_pack/abc/__init__.py +0 -2
- amulet/resource_pack/abc/resource_pack.py +0 -38
- amulet/resource_pack/abc/resource_pack_manager.py +0 -87
- amulet/resource_pack/bedrock/__init__.py +0 -2
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/pack_icon.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/grass_carried.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/grass_side_carried.png +0 -0
- amulet/resource_pack/bedrock/bedrock_vanilla_fix/textures/blocks/water.png +0 -0
- amulet/resource_pack/bedrock/blockshapes/__init__.py +0 -31
- amulet/resource_pack/bedrock/blockshapes/air.py +0 -35
- amulet/resource_pack/bedrock/blockshapes/base_blockshape.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/bubble_column.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/cake.py +0 -46
- amulet/resource_pack/bedrock/blockshapes/chest.py +0 -54
- amulet/resource_pack/bedrock/blockshapes/comparator.py +0 -51
- amulet/resource_pack/bedrock/blockshapes/cross_texture.py +0 -186
- amulet/resource_pack/bedrock/blockshapes/cross_texture0.py +0 -17
- amulet/resource_pack/bedrock/blockshapes/cross_texture_green.py +0 -16
- amulet/resource_pack/bedrock/blockshapes/cube.py +0 -38
- amulet/resource_pack/bedrock/blockshapes/default.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door.py +0 -38
- amulet/resource_pack/bedrock/blockshapes/door1.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door2.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door3.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door4.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door5.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/door6.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/double_plant.py +0 -40
- amulet/resource_pack/bedrock/blockshapes/enchanting_table.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/farmland.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/fence.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/flat.py +0 -55
- amulet/resource_pack/bedrock/blockshapes/flat_wall.py +0 -55
- amulet/resource_pack/bedrock/blockshapes/furnace.py +0 -44
- amulet/resource_pack/bedrock/blockshapes/furnace_lit.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/green_cube.py +0 -39
- amulet/resource_pack/bedrock/blockshapes/ladder.py +0 -36
- amulet/resource_pack/bedrock/blockshapes/lilypad.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/partial_block.py +0 -57
- amulet/resource_pack/bedrock/blockshapes/piston.py +0 -44
- amulet/resource_pack/bedrock/blockshapes/piston_arm.py +0 -72
- amulet/resource_pack/bedrock/blockshapes/portal_frame.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/pressure_plate.py +0 -29
- amulet/resource_pack/bedrock/blockshapes/pumpkin.py +0 -36
- amulet/resource_pack/bedrock/blockshapes/pumpkin_carved.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/pumpkin_lit.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/red_dust.py +0 -14
- amulet/resource_pack/bedrock/blockshapes/repeater.py +0 -53
- amulet/resource_pack/bedrock/blockshapes/slab.py +0 -33
- amulet/resource_pack/bedrock/blockshapes/slab_double.py +0 -15
- amulet/resource_pack/bedrock/blockshapes/tree.py +0 -41
- amulet/resource_pack/bedrock/blockshapes/turtle_egg.py +0 -15
- amulet/resource_pack/bedrock/blockshapes/vine.py +0 -52
- amulet/resource_pack/bedrock/blockshapes/wall.py +0 -22
- amulet/resource_pack/bedrock/blockshapes/water.py +0 -38
- amulet/resource_pack/bedrock/download_resources.py +0 -147
- amulet/resource_pack/bedrock/resource_pack.py +0 -40
- amulet/resource_pack/bedrock/resource_pack_manager.py +0 -361
- amulet/resource_pack/bedrock/sort_blockshapes.py +0 -15
- amulet/resource_pack/java/__init__.py +0 -2
- amulet/resource_pack/java/download_resources.py +0 -212
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_black.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_brown.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_cyan.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_green.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_blue.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_light_gray.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_lime.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_magenta.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_orange.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_pink.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_purple.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_red.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_white.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/banner/banner_yellow.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/barrier.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/end_portal.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/grass.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/lava.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/structure_void.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/assets/minecraft/textures/block/water.png +0 -0
- amulet/resource_pack/java/java_vanilla_fix/pack.png +0 -0
- amulet/resource_pack/java/resource_pack.py +0 -44
- amulet/resource_pack/java/resource_pack_manager.py +0 -551
- amulet/resource_pack/unknown_resource_pack.py +0 -10
- amulet/selection/__init__.py +0 -2
- amulet/selection/abstract_selection.py +0 -342
- amulet/selection/box.py +0 -852
- amulet/selection/group.py +0 -481
- amulet/utils/__init__.pyi +0 -23
- amulet/utils/call_spec/__init__.py +0 -24
- amulet/utils/call_spec/_call_spec.py +0 -257
- amulet/utils/comment_json.py +0 -188
- amulet/utils/format_utils.py +0 -41
- amulet/utils/generator.py +0 -18
- amulet/utils/matrix.py +0 -243
- amulet/utils/numpy.hpp +0 -36
- amulet/utils/numpy.pyi +0 -11
- amulet/utils/numpy_helpers.py +0 -19
- amulet/utils/shareable_lock.py +0 -335
- amulet/utils/signal/__init__.py +0 -10
- amulet/utils/signal/_signal.py +0 -228
- amulet/utils/task_manager.py +0 -235
- amulet/utils/typed_property.py +0 -111
- amulet/utils/weakref.py +0 -70
- amulet/utils/world_utils.py +0 -102
- amulet/version.cpp +0 -136
- amulet/version.hpp +0 -142
- amulet/version.py.cpp +0 -281
- amulet_core-2.0a7.dist-info/RECORD +0 -295
- amulet_core-2.0a7.dist-info/entry_points.txt +0 -2
- /amulet/{__pyinstaller → core/__pyinstaller}/__init__.py +0 -0
- /amulet/{py.typed → core/py.typed} +0 -0
- {amulet_core-2.0a7.dist-info → amulet_core-2.0.1.0.1297307203.19.43.34808.0a0.dist-info}/top_level.txt +0 -0
|
@@ -1,553 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
from typing import overload, Literal, TypeVar
|
|
3
|
-
from dataclasses import dataclass, field
|
|
4
|
-
from copy import deepcopy
|
|
5
|
-
from enum import Enum
|
|
6
|
-
|
|
7
|
-
# section_string is a raw string containing section (§) codes
|
|
8
|
-
# raw text is a stringified json object
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
@dataclass(frozen=True)
|
|
12
|
-
class Colour:
|
|
13
|
-
r: int
|
|
14
|
-
g: int
|
|
15
|
-
b: int
|
|
16
|
-
|
|
17
|
-
def __post_init__(self) -> None:
|
|
18
|
-
assert 0 <= self.r <= 255
|
|
19
|
-
assert 0 <= self.g <= 255
|
|
20
|
-
assert 0 <= self.b <= 255
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class Formatting(Enum):
|
|
24
|
-
Reset = "reset"
|
|
25
|
-
Bold = "bold"
|
|
26
|
-
Italic = "italic"
|
|
27
|
-
Underlined = "underlined"
|
|
28
|
-
Strikethrough = "strikethrough"
|
|
29
|
-
Obfuscated = "obfuscated"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class JavaNameHexColourFactory:
|
|
33
|
-
Colour2Name = {
|
|
34
|
-
Colour(0x00, 0x00, 0x00): "black",
|
|
35
|
-
Colour(0x00, 0x00, 0xAA): "dark_blue",
|
|
36
|
-
Colour(0x00, 0xAA, 0x00): "dark_green",
|
|
37
|
-
Colour(0x00, 0xAA, 0xAA): "dark_aqua",
|
|
38
|
-
Colour(0xAA, 0x00, 0x00): "dark_red",
|
|
39
|
-
Colour(0xAA, 0x00, 0xAA): "dark_purple",
|
|
40
|
-
Colour(0xFF, 0xAA, 0x00): "gold",
|
|
41
|
-
Colour(0xAA, 0xAA, 0xAA): "gray",
|
|
42
|
-
Colour(0x55, 0x55, 0x55): "dark_gray",
|
|
43
|
-
Colour(0x55, 0x55, 0xFF): "blue",
|
|
44
|
-
Colour(0x55, 0xFF, 0x55): "green",
|
|
45
|
-
Colour(0x55, 0xFF, 0xFF): "aqua",
|
|
46
|
-
Colour(0xFF, 0x55, 0x55): "red",
|
|
47
|
-
Colour(0xFF, 0x55, 0xFF): "light_purple",
|
|
48
|
-
Colour(0xFF, 0xFF, 0x55): "yellow",
|
|
49
|
-
Colour(0xFF, 0xFF, 0xFF): "white",
|
|
50
|
-
}
|
|
51
|
-
Name2Colour = {name: colour for colour, name in Colour2Name.items()}
|
|
52
|
-
|
|
53
|
-
@classmethod
|
|
54
|
-
def read(cls, raw_colour: str) -> Colour:
|
|
55
|
-
if raw_colour in cls.Name2Colour:
|
|
56
|
-
return cls.Name2Colour[raw_colour]
|
|
57
|
-
elif raw_colour.startswith("#"):
|
|
58
|
-
num = int(raw_colour[1:], 16)
|
|
59
|
-
r = (num >> 16) & 0xFF
|
|
60
|
-
g = (num >> 8) & 0xFF
|
|
61
|
-
b = num & 0xFF
|
|
62
|
-
return Colour(r, g, b)
|
|
63
|
-
raise ValueError(raw_colour)
|
|
64
|
-
|
|
65
|
-
@classmethod
|
|
66
|
-
def write(cls, colour: Colour) -> str:
|
|
67
|
-
if colour in cls.Colour2Name:
|
|
68
|
-
return cls.Colour2Name[colour]
|
|
69
|
-
else:
|
|
70
|
-
return f"#{colour.r % 256:02X}{colour.g % 256:02X}{colour.b % 256:02X}"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
class AbstractSectionParser:
|
|
74
|
-
"""A class to serialise and deserialise section codes"""
|
|
75
|
-
|
|
76
|
-
Code2Colour: dict[str, Colour] = {}
|
|
77
|
-
Colour2Code: dict[Colour, str] = {}
|
|
78
|
-
Format2Code: dict[Formatting, str]
|
|
79
|
-
Code2Format: dict[str, Formatting]
|
|
80
|
-
|
|
81
|
-
@classmethod
|
|
82
|
-
def read(cls, section_code: str) -> Colour | Formatting | None:
|
|
83
|
-
return cls.Code2Colour.get(section_code) or cls.Code2Format.get(section_code)
|
|
84
|
-
|
|
85
|
-
@classmethod
|
|
86
|
-
def write(cls, value: Colour | Formatting) -> str | None:
|
|
87
|
-
if isinstance(value, Colour):
|
|
88
|
-
if value not in cls.Colour2Code:
|
|
89
|
-
# Find the closest colour to this colour
|
|
90
|
-
# This is a dumb city block search
|
|
91
|
-
value = min(
|
|
92
|
-
cls.Colour2Code,
|
|
93
|
-
key=lambda col: abs(value.r - col.r)
|
|
94
|
-
+ abs(value.g - col.g)
|
|
95
|
-
+ abs(value.b - col.b),
|
|
96
|
-
)
|
|
97
|
-
return cls.Colour2Code[value]
|
|
98
|
-
elif isinstance(value, Formatting) and value in cls.Format2Code:
|
|
99
|
-
return cls.Format2Code[value]
|
|
100
|
-
return None
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
class JavaSectionParser(AbstractSectionParser):
|
|
104
|
-
Colour2Code = {
|
|
105
|
-
Colour(0x00, 0x00, 0x00): "0",
|
|
106
|
-
Colour(0x00, 0x00, 0xAA): "1",
|
|
107
|
-
Colour(0x00, 0xAA, 0x00): "2",
|
|
108
|
-
Colour(0x00, 0xAA, 0xAA): "3",
|
|
109
|
-
Colour(0xAA, 0x00, 0x00): "4",
|
|
110
|
-
Colour(0xAA, 0x00, 0xAA): "5",
|
|
111
|
-
Colour(0xFF, 0xAA, 0x00): "6",
|
|
112
|
-
Colour(0xAA, 0xAA, 0xAA): "7",
|
|
113
|
-
Colour(0x55, 0x55, 0x55): "8",
|
|
114
|
-
Colour(0x55, 0x55, 0xFF): "9",
|
|
115
|
-
Colour(0x55, 0xFF, 0x55): "a",
|
|
116
|
-
Colour(0x55, 0xFF, 0xFF): "b",
|
|
117
|
-
Colour(0xFF, 0x55, 0x55): "c",
|
|
118
|
-
Colour(0xFF, 0x55, 0xFF): "d",
|
|
119
|
-
Colour(0xFF, 0xFF, 0x55): "e",
|
|
120
|
-
Colour(0xFF, 0xFF, 0xFF): "f",
|
|
121
|
-
}
|
|
122
|
-
Code2Colour = {name: colour for colour, name in Colour2Code.items()}
|
|
123
|
-
Format2Code = {
|
|
124
|
-
Formatting.Reset: "r",
|
|
125
|
-
Formatting.Bold: "l",
|
|
126
|
-
Formatting.Strikethrough: "m",
|
|
127
|
-
Formatting.Underlined: "n",
|
|
128
|
-
Formatting.Italic: "o",
|
|
129
|
-
Formatting.Obfuscated: "k",
|
|
130
|
-
}
|
|
131
|
-
Code2Format = {c: f for f, c in Format2Code.items()}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
class BedrockSectionParser(AbstractSectionParser):
|
|
135
|
-
Colour2Code = {
|
|
136
|
-
Colour(0x00, 0x00, 0x00): "0",
|
|
137
|
-
Colour(0x00, 0x00, 0xAA): "1",
|
|
138
|
-
Colour(0x00, 0xAA, 0x00): "2",
|
|
139
|
-
Colour(0x00, 0xAA, 0xAA): "3",
|
|
140
|
-
Colour(0xAA, 0x00, 0x00): "4",
|
|
141
|
-
Colour(0xAA, 0x00, 0xAA): "5",
|
|
142
|
-
Colour(0xFF, 0xAA, 0x00): "6",
|
|
143
|
-
Colour(0xAA, 0xAA, 0xAA): "7",
|
|
144
|
-
Colour(0x55, 0x55, 0x55): "8",
|
|
145
|
-
Colour(0x55, 0x55, 0xFF): "9",
|
|
146
|
-
Colour(0x55, 0xFF, 0x55): "a",
|
|
147
|
-
Colour(0x55, 0xFF, 0xFF): "b",
|
|
148
|
-
Colour(0xFF, 0x55, 0x55): "c",
|
|
149
|
-
Colour(0xFF, 0x55, 0xFF): "d",
|
|
150
|
-
Colour(0xFF, 0xFF, 0x55): "e",
|
|
151
|
-
Colour(0xFF, 0xFF, 0xFF): "f",
|
|
152
|
-
}
|
|
153
|
-
Code2Colour = {name: colour for colour, name in Colour2Code.items()}
|
|
154
|
-
Format2Code = {
|
|
155
|
-
Formatting.Reset: "r",
|
|
156
|
-
Formatting.Bold: "l",
|
|
157
|
-
Formatting.Italic: "o",
|
|
158
|
-
Formatting.Obfuscated: "k",
|
|
159
|
-
}
|
|
160
|
-
Code2Format = {c: f for f, c in Format2Code.items()}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
class ExtendedBedrockSectionParser(AbstractSectionParser):
|
|
164
|
-
Colour2Code = {
|
|
165
|
-
Colour(0x00, 0x00, 0x00): "0",
|
|
166
|
-
Colour(0x00, 0x00, 0xAA): "1",
|
|
167
|
-
Colour(0x00, 0xAA, 0x00): "2",
|
|
168
|
-
Colour(0x00, 0xAA, 0xAA): "3",
|
|
169
|
-
Colour(0xAA, 0x00, 0x00): "4",
|
|
170
|
-
Colour(0xAA, 0x00, 0xAA): "5",
|
|
171
|
-
Colour(0xFF, 0xAA, 0x00): "6",
|
|
172
|
-
Colour(0xAA, 0xAA, 0xAA): "7",
|
|
173
|
-
Colour(0x55, 0x55, 0x55): "8",
|
|
174
|
-
Colour(0x55, 0x55, 0xFF): "9",
|
|
175
|
-
Colour(0x55, 0xFF, 0x55): "a",
|
|
176
|
-
Colour(0x55, 0xFF, 0xFF): "b",
|
|
177
|
-
Colour(0xFF, 0x55, 0x55): "c",
|
|
178
|
-
Colour(0xFF, 0x55, 0xFF): "d",
|
|
179
|
-
Colour(0xFF, 0xFF, 0x55): "e",
|
|
180
|
-
Colour(0xFF, 0xFF, 0xFF): "f",
|
|
181
|
-
Colour(0xDD, 0xD6, 0x05): "g",
|
|
182
|
-
Colour(0xE3, 0xD4, 0xD1): "h",
|
|
183
|
-
Colour(0xCE, 0xCA, 0xCA): "i",
|
|
184
|
-
Colour(0x44, 0x3A, 0x3B): "j",
|
|
185
|
-
Colour(0x97, 0x16, 0x07): "m",
|
|
186
|
-
Colour(0xB4, 0x68, 0x4D): "n",
|
|
187
|
-
Colour(0xDE, 0xB1, 0x2D): "p",
|
|
188
|
-
Colour(0x47, 0xA0, 0x36): "q",
|
|
189
|
-
Colour(0x2C, 0xBA, 0xA8): "s",
|
|
190
|
-
Colour(0x21, 0x49, 0x7B): "t",
|
|
191
|
-
Colour(0x9A, 0x5C, 0xC6): "u",
|
|
192
|
-
}
|
|
193
|
-
Code2Colour = {name: colour for colour, name in Colour2Code.items()}
|
|
194
|
-
Format2Code = {
|
|
195
|
-
Formatting.Reset: "r",
|
|
196
|
-
Formatting.Bold: "l",
|
|
197
|
-
Formatting.Italic: "o",
|
|
198
|
-
Formatting.Obfuscated: "k",
|
|
199
|
-
}
|
|
200
|
-
Code2Format = {c: f for f, c in Format2Code.items()}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
@dataclass
|
|
204
|
-
class RawTextFormatting:
|
|
205
|
-
colour: Colour | None = None
|
|
206
|
-
bold: bool | None = None
|
|
207
|
-
italic: bool | None = None
|
|
208
|
-
underlined: bool | None = None
|
|
209
|
-
strikethrough: bool | None = None
|
|
210
|
-
obfuscated: bool | None = None
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
T = TypeVar("T")
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
@dataclass
|
|
217
|
-
class RawTextComponent:
|
|
218
|
-
"""
|
|
219
|
-
This class supports the core subset of the full raw text specification.
|
|
220
|
-
This is not an attempt to support the full specification.
|
|
221
|
-
"""
|
|
222
|
-
|
|
223
|
-
text: str = ""
|
|
224
|
-
formatting: RawTextFormatting = field(default_factory=RawTextFormatting)
|
|
225
|
-
children: list[RawTextComponent] = field(default_factory=list)
|
|
226
|
-
|
|
227
|
-
@classmethod
|
|
228
|
-
def from_java_raw_text(
|
|
229
|
-
cls, obj: str | bool | float | list | dict
|
|
230
|
-
) -> RawTextComponent:
|
|
231
|
-
"""
|
|
232
|
-
Parse a raw JSON text object and unpack it into this class.
|
|
233
|
-
Note that the input is not a raw JSON string but the result from json.loads
|
|
234
|
-
"""
|
|
235
|
-
if isinstance(obj, str):
|
|
236
|
-
return cls.from_java_raw_text({"text": obj})
|
|
237
|
-
elif isinstance(obj, bool):
|
|
238
|
-
return cls.from_java_raw_text("true" if obj else "false")
|
|
239
|
-
elif isinstance(obj, float):
|
|
240
|
-
return cls.from_java_raw_text(str(obj))
|
|
241
|
-
elif isinstance(obj, list):
|
|
242
|
-
if obj:
|
|
243
|
-
self = cls.from_java_raw_text(obj[0])
|
|
244
|
-
for el in obj[1:]:
|
|
245
|
-
self.children.append(cls.from_java_raw_text(el))
|
|
246
|
-
return self
|
|
247
|
-
else:
|
|
248
|
-
return cls.from_java_raw_text("")
|
|
249
|
-
elif isinstance(obj, dict):
|
|
250
|
-
text = obj.pop("text", "")
|
|
251
|
-
if isinstance(text, bool):
|
|
252
|
-
text = "true" if text else "false"
|
|
253
|
-
else:
|
|
254
|
-
text = str(text)
|
|
255
|
-
|
|
256
|
-
extra: list = obj.pop("extra", None)
|
|
257
|
-
children: list[RawTextComponent] = (
|
|
258
|
-
[cls.from_java_raw_text(child) for child in extra]
|
|
259
|
-
if isinstance(extra, list)
|
|
260
|
-
else []
|
|
261
|
-
)
|
|
262
|
-
|
|
263
|
-
def get_bool(key: str) -> bool | None:
|
|
264
|
-
val = obj.get(key)
|
|
265
|
-
if isinstance(val, bool):
|
|
266
|
-
return val
|
|
267
|
-
return None
|
|
268
|
-
|
|
269
|
-
bold = get_bool("bold")
|
|
270
|
-
italic = get_bool("italic")
|
|
271
|
-
underlined = get_bool("underlined")
|
|
272
|
-
strikethrough = get_bool("strikethrough")
|
|
273
|
-
obfuscated = get_bool("obfuscated")
|
|
274
|
-
|
|
275
|
-
colour_text = obj.get("color")
|
|
276
|
-
if isinstance(colour_text, str):
|
|
277
|
-
colour = JavaNameHexColourFactory.read(colour_text)
|
|
278
|
-
else:
|
|
279
|
-
colour = None
|
|
280
|
-
|
|
281
|
-
return cls(
|
|
282
|
-
text,
|
|
283
|
-
RawTextFormatting(
|
|
284
|
-
colour,
|
|
285
|
-
bold,
|
|
286
|
-
italic,
|
|
287
|
-
underlined,
|
|
288
|
-
strikethrough,
|
|
289
|
-
obfuscated,
|
|
290
|
-
),
|
|
291
|
-
children,
|
|
292
|
-
)
|
|
293
|
-
else:
|
|
294
|
-
raise TypeError
|
|
295
|
-
|
|
296
|
-
def to_java_raw_text(self) -> str | dict:
|
|
297
|
-
component: dict[str, list | str | bool] = {"text": self.text}
|
|
298
|
-
if self.children:
|
|
299
|
-
component["extra"] = [child.to_java_raw_text() for child in self.children]
|
|
300
|
-
if self.formatting.colour is not None:
|
|
301
|
-
component["color"] = JavaNameHexColourFactory.write(self.formatting.colour)
|
|
302
|
-
if self.formatting.bold is not None:
|
|
303
|
-
component["bold"] = self.formatting.bold
|
|
304
|
-
if self.formatting.italic is not None:
|
|
305
|
-
component["italic"] = self.formatting.italic
|
|
306
|
-
if self.formatting.underlined is not None:
|
|
307
|
-
component["underlined"] = self.formatting.underlined
|
|
308
|
-
if self.formatting.strikethrough is not None:
|
|
309
|
-
component["strikethrough"] = self.formatting.strikethrough
|
|
310
|
-
if self.formatting.obfuscated is not None:
|
|
311
|
-
component["obfuscated"] = self.formatting.obfuscated
|
|
312
|
-
if component.keys() == {"text"}:
|
|
313
|
-
return self.text
|
|
314
|
-
else:
|
|
315
|
-
return component
|
|
316
|
-
|
|
317
|
-
@overload
|
|
318
|
-
@classmethod
|
|
319
|
-
def from_section_text(
|
|
320
|
-
cls, section_text: str, section_parser: type[AbstractSectionParser]
|
|
321
|
-
) -> RawTextComponent: ...
|
|
322
|
-
|
|
323
|
-
@overload
|
|
324
|
-
@classmethod
|
|
325
|
-
def from_section_text(
|
|
326
|
-
cls,
|
|
327
|
-
section_text: str,
|
|
328
|
-
section_parser: type[AbstractSectionParser],
|
|
329
|
-
split_newline: Literal[False],
|
|
330
|
-
) -> RawTextComponent: ...
|
|
331
|
-
|
|
332
|
-
@overload
|
|
333
|
-
@classmethod
|
|
334
|
-
def from_section_text(
|
|
335
|
-
cls,
|
|
336
|
-
section_text: str,
|
|
337
|
-
section_parser: type[AbstractSectionParser],
|
|
338
|
-
split_newline: Literal[True],
|
|
339
|
-
) -> list[RawTextComponent]: ...
|
|
340
|
-
|
|
341
|
-
@classmethod
|
|
342
|
-
def from_section_text(
|
|
343
|
-
cls,
|
|
344
|
-
section_text: str,
|
|
345
|
-
section_parser: type[AbstractSectionParser],
|
|
346
|
-
split_newline: bool = False,
|
|
347
|
-
) -> RawTextComponent | list[RawTextComponent]:
|
|
348
|
-
"""Parse a section string and convert it to raw JSON text format."""
|
|
349
|
-
# Completed lines
|
|
350
|
-
lines: list[RawTextComponent] = []
|
|
351
|
-
# Components that make up this line
|
|
352
|
-
components: list[RawTextComponent] = []
|
|
353
|
-
|
|
354
|
-
# The formatting found so far in the line
|
|
355
|
-
formatting = RawTextFormatting()
|
|
356
|
-
|
|
357
|
-
# The character index in the string
|
|
358
|
-
index = 0
|
|
359
|
-
max_index = len(section_text)
|
|
360
|
-
|
|
361
|
-
# The index of the next section character and newline.
|
|
362
|
-
# If not found, these equal the length of the string
|
|
363
|
-
next_section_index = section_text.find("§", index) % (max_index + 1)
|
|
364
|
-
next_newline_index = (
|
|
365
|
-
section_text.find("\n", index) % (max_index + 1)
|
|
366
|
-
if split_newline
|
|
367
|
-
else max_index
|
|
368
|
-
)
|
|
369
|
-
|
|
370
|
-
def append_section(text: str) -> None:
|
|
371
|
-
if text:
|
|
372
|
-
components.append(cls(text, deepcopy(formatting)))
|
|
373
|
-
|
|
374
|
-
def append_line() -> None:
|
|
375
|
-
# Push all components to a new line
|
|
376
|
-
lines.append(cls(children=components.copy()))
|
|
377
|
-
components.clear()
|
|
378
|
-
|
|
379
|
-
while True:
|
|
380
|
-
if next_section_index < next_newline_index:
|
|
381
|
-
# section char first
|
|
382
|
-
|
|
383
|
-
if next_section_index > index:
|
|
384
|
-
append_section(section_text[index:next_section_index])
|
|
385
|
-
|
|
386
|
-
index = next_section_index + 1
|
|
387
|
-
section_code = section_text[index : index + 1]
|
|
388
|
-
value = section_parser.read(section_code)
|
|
389
|
-
if isinstance(value, Formatting):
|
|
390
|
-
if value is Formatting.Obfuscated: # obfuscated
|
|
391
|
-
formatting.obfuscated = True
|
|
392
|
-
index += 1
|
|
393
|
-
elif value is Formatting.Bold: # bold
|
|
394
|
-
formatting.bold = True
|
|
395
|
-
index += 1
|
|
396
|
-
elif value is Formatting.Strikethrough: # strikethrough
|
|
397
|
-
formatting.strikethrough = True
|
|
398
|
-
index += 1
|
|
399
|
-
elif value is Formatting.Underlined: # underlined
|
|
400
|
-
formatting.underlined = True
|
|
401
|
-
index += 1
|
|
402
|
-
elif value is Formatting.Italic: # italic
|
|
403
|
-
formatting.italic = True
|
|
404
|
-
index += 1
|
|
405
|
-
elif value is Formatting.Reset: # reset
|
|
406
|
-
formatting.obfuscated = False
|
|
407
|
-
formatting.bold = False
|
|
408
|
-
formatting.strikethrough = False
|
|
409
|
-
formatting.underlined = False
|
|
410
|
-
formatting.italic = False
|
|
411
|
-
formatting.colour = None
|
|
412
|
-
index += 1
|
|
413
|
-
elif isinstance(value, Colour):
|
|
414
|
-
formatting.colour = value
|
|
415
|
-
index += 1
|
|
416
|
-
|
|
417
|
-
next_section_index = section_text.find("§", index) % (max_index + 1)
|
|
418
|
-
|
|
419
|
-
elif next_newline_index == max_index:
|
|
420
|
-
# No more in the string
|
|
421
|
-
append_section(section_text[index:])
|
|
422
|
-
append_line()
|
|
423
|
-
break
|
|
424
|
-
|
|
425
|
-
elif split_newline:
|
|
426
|
-
# newline first
|
|
427
|
-
|
|
428
|
-
append_section(section_text[index:next_newline_index])
|
|
429
|
-
append_line()
|
|
430
|
-
|
|
431
|
-
index = next_newline_index + 1
|
|
432
|
-
next_newline_index = section_text.find("\n", index) % (max_index + 1)
|
|
433
|
-
else:
|
|
434
|
-
raise RuntimeError
|
|
435
|
-
|
|
436
|
-
def compact(src: RawTextComponent) -> RawTextComponent:
|
|
437
|
-
if len(src.children) == 1:
|
|
438
|
-
# Don't need the parent node
|
|
439
|
-
return src.children[0]
|
|
440
|
-
return src
|
|
441
|
-
|
|
442
|
-
if split_newline:
|
|
443
|
-
return list(map(compact, lines))
|
|
444
|
-
else:
|
|
445
|
-
return compact(lines[0])
|
|
446
|
-
|
|
447
|
-
def to_section_text(self, section_parser: type[AbstractSectionParser]) -> str:
|
|
448
|
-
"""
|
|
449
|
-
Convert the raw text object to a section text string
|
|
450
|
-
:param section_parser: The colour palette to use.
|
|
451
|
-
:return: The section text.
|
|
452
|
-
"""
|
|
453
|
-
|
|
454
|
-
text: list[str] = []
|
|
455
|
-
|
|
456
|
-
current_formatting = RawTextFormatting()
|
|
457
|
-
|
|
458
|
-
reset_code = section_parser.write(Formatting.Reset)
|
|
459
|
-
bold_code = section_parser.write(Formatting.Bold)
|
|
460
|
-
italic_code = section_parser.write(Formatting.Italic)
|
|
461
|
-
underlined_code = section_parser.write(Formatting.Underlined)
|
|
462
|
-
strikethrough_code = section_parser.write(Formatting.Strikethrough)
|
|
463
|
-
obfuscated_code = section_parser.write(Formatting.Obfuscated)
|
|
464
|
-
|
|
465
|
-
def merge_formatting(
|
|
466
|
-
a: RawTextFormatting, b: RawTextFormatting
|
|
467
|
-
) -> RawTextFormatting:
|
|
468
|
-
# Merge b into a
|
|
469
|
-
return RawTextFormatting(
|
|
470
|
-
a.colour if b.colour is None else b.colour,
|
|
471
|
-
a.bold if b.bold is None else b.bold,
|
|
472
|
-
a.italic if b.italic is None else b.italic,
|
|
473
|
-
a.underlined if b.underlined is None else b.underlined,
|
|
474
|
-
a.strikethrough if b.strikethrough is None else b.strikethrough,
|
|
475
|
-
a.obfuscated if b.obfuscated is None else b.obfuscated,
|
|
476
|
-
)
|
|
477
|
-
|
|
478
|
-
def to_section_text(
|
|
479
|
-
section: RawTextComponent, parent_formatting: RawTextFormatting
|
|
480
|
-
) -> None:
|
|
481
|
-
desired_formatting = merge_formatting(parent_formatting, section.formatting)
|
|
482
|
-
|
|
483
|
-
if section.text:
|
|
484
|
-
if (
|
|
485
|
-
(
|
|
486
|
-
current_formatting.colour is not None
|
|
487
|
-
and desired_formatting.colour is None
|
|
488
|
-
)
|
|
489
|
-
or (current_formatting.bold and not desired_formatting.bold)
|
|
490
|
-
or (current_formatting.italic and not desired_formatting.italic)
|
|
491
|
-
or (
|
|
492
|
-
current_formatting.underlined
|
|
493
|
-
and not desired_formatting.underlined
|
|
494
|
-
)
|
|
495
|
-
or (
|
|
496
|
-
current_formatting.strikethrough
|
|
497
|
-
and not desired_formatting.strikethrough
|
|
498
|
-
)
|
|
499
|
-
or (
|
|
500
|
-
current_formatting.obfuscated
|
|
501
|
-
and not desired_formatting.obfuscated
|
|
502
|
-
)
|
|
503
|
-
):
|
|
504
|
-
# A property has been unset. Reset the formatting and apply everything again
|
|
505
|
-
if reset_code is not None:
|
|
506
|
-
text.append(f"§{reset_code}")
|
|
507
|
-
current_formatting.colour = None
|
|
508
|
-
current_formatting.bold = False
|
|
509
|
-
current_formatting.italic = False
|
|
510
|
-
current_formatting.underlined = False
|
|
511
|
-
current_formatting.strikethrough = False
|
|
512
|
-
current_formatting.obfuscated = False
|
|
513
|
-
|
|
514
|
-
# If the formatting has been set and the original formatting is not set
|
|
515
|
-
if desired_formatting.bold and not current_formatting.bold:
|
|
516
|
-
if bold_code is not None:
|
|
517
|
-
text.append(f"§{bold_code}")
|
|
518
|
-
current_formatting.bold = True
|
|
519
|
-
if desired_formatting.italic and not current_formatting.italic:
|
|
520
|
-
if italic_code is not None:
|
|
521
|
-
text.append(f"§{italic_code}")
|
|
522
|
-
current_formatting.italic = True
|
|
523
|
-
if desired_formatting.underlined and not current_formatting.underlined:
|
|
524
|
-
if underlined_code is not None:
|
|
525
|
-
text.append(f"§{underlined_code}")
|
|
526
|
-
current_formatting.underlined = True
|
|
527
|
-
if (
|
|
528
|
-
desired_formatting.strikethrough
|
|
529
|
-
and not current_formatting.strikethrough
|
|
530
|
-
):
|
|
531
|
-
if strikethrough_code is not None:
|
|
532
|
-
text.append(f"§{strikethrough_code}")
|
|
533
|
-
current_formatting.strikethrough = True
|
|
534
|
-
if desired_formatting.obfuscated and not current_formatting.obfuscated:
|
|
535
|
-
if obfuscated_code is not None:
|
|
536
|
-
text.append(f"§{obfuscated_code}")
|
|
537
|
-
current_formatting.obfuscated = True
|
|
538
|
-
if (
|
|
539
|
-
desired_formatting.colour is not None
|
|
540
|
-
and desired_formatting.colour != current_formatting.colour
|
|
541
|
-
):
|
|
542
|
-
code = section_parser.write(desired_formatting.colour)
|
|
543
|
-
assert code is not None
|
|
544
|
-
text.append("§" + code)
|
|
545
|
-
current_formatting.colour = desired_formatting.colour
|
|
546
|
-
|
|
547
|
-
text.append(section.text)
|
|
548
|
-
|
|
549
|
-
for child in section.children:
|
|
550
|
-
to_section_text(child, desired_formatting)
|
|
551
|
-
|
|
552
|
-
to_section_text(self, RawTextFormatting())
|
|
553
|
-
return "".join(text)
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
from amulet_nbt import CompoundTag, ListTag, IntTag
|
|
2
|
-
from .._state import SrcData, StateData, DstData
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
def to_universal(src: SrcData, state: StateData, dst: DstData) -> None:
|
|
6
|
-
nbt = src.nbt
|
|
7
|
-
if nbt is None:
|
|
8
|
-
return
|
|
9
|
-
|
|
10
|
-
tag = nbt.tag
|
|
11
|
-
if not isinstance(tag, CompoundTag):
|
|
12
|
-
return
|
|
13
|
-
|
|
14
|
-
patterns = tag.get("Patterns")
|
|
15
|
-
if not isinstance(patterns, ListTag):
|
|
16
|
-
return
|
|
17
|
-
|
|
18
|
-
for index, pattern in enumerate(patterns):
|
|
19
|
-
if not isinstance(pattern, CompoundTag):
|
|
20
|
-
continue
|
|
21
|
-
colour = pattern.get("Color")
|
|
22
|
-
if not isinstance(colour, IntTag):
|
|
23
|
-
continue
|
|
24
|
-
|
|
25
|
-
dst.nbt.append(
|
|
26
|
-
(
|
|
27
|
-
"",
|
|
28
|
-
CompoundTag,
|
|
29
|
-
(("utags", CompoundTag), ("Patterns", ListTag), (index, CompoundTag)),
|
|
30
|
-
"Color",
|
|
31
|
-
IntTag(15 - colour.py_int),
|
|
32
|
-
)
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def from_universal(src: SrcData, state: StateData, dst: DstData) -> None:
|
|
37
|
-
nbt = src.nbt
|
|
38
|
-
if nbt is None:
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
tag = nbt.tag
|
|
42
|
-
if not isinstance(tag, CompoundTag):
|
|
43
|
-
return
|
|
44
|
-
|
|
45
|
-
utags = tag.get("utags")
|
|
46
|
-
if not isinstance(utags, CompoundTag):
|
|
47
|
-
return
|
|
48
|
-
|
|
49
|
-
patterns = utags.get("Patterns")
|
|
50
|
-
if not isinstance(patterns, ListTag):
|
|
51
|
-
return
|
|
52
|
-
|
|
53
|
-
for index, pattern in enumerate(patterns):
|
|
54
|
-
if not isinstance(pattern, CompoundTag):
|
|
55
|
-
continue
|
|
56
|
-
colour = pattern.get("Color")
|
|
57
|
-
if not isinstance(colour, IntTag):
|
|
58
|
-
continue
|
|
59
|
-
dst.nbt.append(
|
|
60
|
-
(
|
|
61
|
-
"",
|
|
62
|
-
CompoundTag,
|
|
63
|
-
(("Patterns", ListTag), (index, CompoundTag)),
|
|
64
|
-
"Color",
|
|
65
|
-
IntTag(15 - colour.py_int),
|
|
66
|
-
)
|
|
67
|
-
)
|