stewbeet 2.0.6__tar.gz → 2.0.8__tar.gz

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 stewbeet might be problematic. Click here for more details.

Files changed (137) hide show
  1. {stewbeet-2.0.6 → stewbeet-2.0.8}/PKG-INFO +2 -2
  2. {stewbeet-2.0.6 → stewbeet-2.0.8}/pyproject.toml +2 -2
  3. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/utils/sounds.py +13 -0
  4. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/archive/__init__.py +0 -30
  5. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/auto/lang_file/__init__.py +37 -39
  6. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/auto/lang_file/utils.py +9 -17
  7. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/copy_to_destination/__init__.py +18 -16
  8. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/datapack/custom_blocks/__init__.py +18 -8
  9. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/finalyze/dependencies/__init__.py +1 -1
  10. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/main.py +1 -2
  11. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/initialize/__init__.py +9 -4
  12. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/resource_pack/item_models/object.py +3 -1
  13. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/verify_definitions/__init__.py +5 -5
  14. {stewbeet-2.0.6 → stewbeet-2.0.8}/.gitignore +0 -0
  15. {stewbeet-2.0.6 → stewbeet-2.0.8}/LICENSE +0 -0
  16. {stewbeet-2.0.6 → stewbeet-2.0.8}/README.md +0 -0
  17. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/__init__.py +0 -0
  18. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/__main__.py +0 -0
  19. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/cli.py +0 -0
  20. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/continuous_delivery/__init__.py +0 -0
  21. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/continuous_delivery/cd_utils.py +0 -0
  22. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/continuous_delivery/github.py +0 -0
  23. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/continuous_delivery/modrinth.py +0 -0
  24. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/continuous_delivery/pmc.py +0 -0
  25. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/continuous_delivery/smithed.py +0 -0
  26. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/__init__.py +0 -0
  27. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/__memory__.py +0 -0
  28. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/constants.py +0 -0
  29. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/definitions_helper/__init__.py +0 -0
  30. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/definitions_helper/completion.py +0 -0
  31. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/definitions_helper/equipments.py +0 -0
  32. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/definitions_helper/materials.py +0 -0
  33. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/definitions_helper/records.py +0 -0
  34. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/definitions_helper/smart_ore_generation.py +0 -0
  35. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/definitions_helper/text.py +0 -0
  36. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/ingredients.py +0 -0
  37. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/core/utils/io.py +0 -0
  38. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/__init__.py +0 -0
  39. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/bookshelf.py +0 -0
  40. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/bookshelf_config.json +0 -0
  41. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Bitwise.zip +0 -0
  42. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Block.zip +0 -0
  43. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Color.zip +0 -0
  44. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Dump.zip +0 -0
  45. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Environment.zip +0 -0
  46. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Generation.zip +0 -0
  47. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Health.zip +0 -0
  48. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Hitbox.zip +0 -0
  49. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Id.zip +0 -0
  50. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Interaction.zip +0 -0
  51. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Link.zip +0 -0
  52. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Log.zip +0 -0
  53. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Math.zip +0 -0
  54. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Move.zip +0 -0
  55. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Position.zip +0 -0
  56. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Random.zip +0 -0
  57. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Raycast.zip +0 -0
  58. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Schedule.zip +0 -0
  59. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Sidebar.zip +0 -0
  60. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Spline.zip +0 -0
  61. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf String.zip +0 -0
  62. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Time.zip +0 -0
  63. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Tree.zip +0 -0
  64. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Vector.zip +0 -0
  65. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf View.zip +0 -0
  66. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Bookshelf Xp.zip +0 -0
  67. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Common Signals.zip +0 -0
  68. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Furnace NBT Recipes.zip +0 -0
  69. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/ItemIO.zip +0 -0
  70. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/SmartOreGeneration.zip +0 -0
  71. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Smithed Crafter.zip +0 -0
  72. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/datapack/Smithed Custom Block.zip +0 -0
  73. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/dependencies/resource_pack/Smithed Crafter.zip +0 -0
  74. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/auto/headers/__init__.py +0 -0
  75. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/auto/headers/object.py +0 -0
  76. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/compatibilities/neo_enchant/__init__.py +0 -0
  77. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/compatibilities/simpledrawer/__init__.py +0 -0
  78. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/compute_sha1/__init__.py +0 -0
  79. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/custom_recipes/__init__.py +0 -0
  80. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/custom_recipes/furnace.py +0 -0
  81. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/custom_recipes/pulverizer.py +0 -0
  82. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/custom_recipes/smithed.py +0 -0
  83. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/custom_recipes/vanilla.py +0 -0
  84. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/datapack/loading/__init__.py +0 -0
  85. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/datapack/loot_tables/__init__.py +0 -0
  86. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/finalyze/basic_datapack_structure/__init__.py +0 -0
  87. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/finalyze/check_unused_textures/__init__.py +0 -0
  88. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/finalyze/custom_blocks_ticking/__init__.py +0 -0
  89. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/__init__.py +0 -0
  90. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/furnace.png +0 -0
  91. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/heavy_workbench.png +0 -0
  92. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/invisible_item.png +0 -0
  93. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/invisible_item_release.png +0 -0
  94. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/minecraft_font.ttf +0 -0
  95. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/none.png +0 -0
  96. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/none_release.png +0 -0
  97. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/pulverizing.png +0 -0
  98. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/shaped_2x2.png +0 -0
  99. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/shaped_3x3.png +0 -0
  100. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/simple_case_no_border.png +0 -0
  101. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/wiki_information.png +0 -0
  102. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/wiki_ingredient_of_craft.png +0 -0
  103. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/wiki_ingredient_of_craft_template.png +0 -0
  104. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/assets/wiki_result_of_craft.png +0 -0
  105. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/book_components.py +0 -0
  106. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/book_optimizer.py +0 -0
  107. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/craft_content.py +0 -0
  108. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/image_utils.py +0 -0
  109. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/iso_renders.py +0 -0
  110. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/other_utils.py +0 -0
  111. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/page_font.py +0 -0
  112. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/shared_import.py +0 -0
  113. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/.gitignore +0 -0
  114. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/_README.md +0 -0
  115. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/furnace.png +0 -0
  116. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/heavy_workbench.png +0 -0
  117. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/invisible_item.png +0 -0
  118. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/invisible_item_release.png +0 -0
  119. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/minecraft_font.ttf +0 -0
  120. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/none.png +0 -0
  121. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/none_release.png +0 -0
  122. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/pulverizing.png +0 -0
  123. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/shaped_2x2.png +0 -0
  124. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/shaped_3x3.png +0 -0
  125. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/simple_case_no_border.png +0 -0
  126. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/wiki_information.png +0 -0
  127. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/wiki_ingredient_of_craft.png +0 -0
  128. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/wiki_ingredient_of_craft_template.png +0 -0
  129. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/templates/wiki_result_of_craft.png +0 -0
  130. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/ingame_manual/text_components.py +0 -0
  131. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/initialize/source_lore_font.py +0 -0
  132. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/merge_smithed_weld/__init__.py +0 -0
  133. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/merge_smithed_weld/weld.py +0 -0
  134. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/resource_pack/check_power_of_2/__init__.py +0 -0
  135. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/resource_pack/item_models/__init__.py +0 -0
  136. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/plugins/resource_pack/sounds/__init__.py +0 -0
  137. {stewbeet-2.0.6 → stewbeet-2.0.8}/stewbeet/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: stewbeet
3
- Version: 2.0.6
3
+ Version: 2.0.8
4
4
  Summary: Beet Framework made to help generating advanced Minecraft datapack contents
5
5
  Project-URL: Homepage, https://github.com/Stoupy51/stewbeet
6
6
  Project-URL: Issues, https://github.com/Stoupy51/stewbeet/issues
@@ -18,7 +18,7 @@ Requires-Dist: model-resolver>=1.8.0
18
18
  Requires-Dist: mutagen>=1.47.0
19
19
  Requires-Dist: pyperclip>=1.8.0
20
20
  Requires-Dist: smithed>=0.19.0
21
- Requires-Dist: stouputils>=1.3.15
21
+ Requires-Dist: stouputils>=1.3.16
22
22
  Description-Content-Type: text/markdown
23
23
 
24
24
 
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
 
6
6
  [project]
7
7
  name = "stewbeet"
8
- version = "2.0.6"
8
+ version = "2.0.8"
9
9
  description = "Beet Framework made to help generating advanced Minecraft datapack contents"
10
10
  readme = "README.md"
11
11
  license = "MIT"
@@ -16,7 +16,7 @@ classifiers = [
16
16
  "Operating System :: OS Independent",
17
17
  ]
18
18
  dependencies = [
19
- "stouputils>=1.3.15",
19
+ "stouputils>=1.3.16",
20
20
  "model_resolver>=1.8.0",
21
21
  "beet>=0.110.1",
22
22
  "bolt>=0.49.1",
@@ -9,6 +9,19 @@ from stouputils.io import super_json_dump
9
9
  def add_sound(ctx: Context, sounds: Sound | dict[str, Sound], name: str, ns: str = ""):
10
10
  """ Add a sound to the resource pack.
11
11
 
12
+ Example usage:
13
+
14
+ ```python
15
+ from beet import Context, Sound
16
+ from stewbeet.core.utils.sounds import add_sound
17
+
18
+ def beet_default(ctx: Context):
19
+ sound = Sound("path/to/sound.ogg", volume=1.0, pitch=1.0)
20
+ add_sound(ctx, sound, "my_sound")
21
+ add_sound(ctx, {"my_sound_1": sound, "my_sound_2": sound}, "my_sounds")
22
+ add_sound(ctx, sound, "my_sound", ns="another_namespace")
23
+ ```
24
+
12
25
  Args:
13
26
  ctx (Context): The beet context.
14
27
  sounds (Sound | dict[str, Sound]): The sound object(s) to add. Can be a single Sound or a dict mapping local names to Sounds.
@@ -1,33 +1,3 @@
1
- """
2
- StewBeet Archive Plugin
3
-
4
- This plugin replaces the legacy `make_archive.py` system with a beet-compatible implementation.
5
- Instead of using the old `FILES_TO_WRITE` global dictionary approach, this plugin leverages
6
- beet's native Context and pack management system.
7
-
8
- Key improvements over the legacy system:
9
- 1. Uses beet's Context.packs to access generated data and resource packs
10
- 2. Uses pack.dump() to create zip archives without interfering with existing pack directories
11
- 3. Integrates with beet's output directory management
12
- 4. Provides proper error handling for file operations
13
- 5. Uses beet cache .gitignore file modification time for consistent, reproducible timestamps
14
-
15
- The plugin automatically:
16
- - Detects all generated packs (data pack and resource pack)
17
- - Creates zip archives with consistent timestamps based on beet cache .gitignore file
18
- - Applies deterministic compression settings for reproducible builds
19
- - Saves archives to the configured output directory
20
- - Preserves existing pack directory structure
21
-
22
- Timestamp Strategy:
23
- The plugin uses the modification time of the `.beet_cache/.gitignore` file to ensure
24
- all zip entries have consistent timestamps, making the archives reproducible and
25
- deterministic across builds. This approach is more reliable than searching for
26
- pack.mcmeta files in the output directory.
27
-
28
- This replaces the legacy make_archive() function calls and integrates seamlessly
29
- with beet's plugin architecture and build pipeline without deleting the original pack folders.
30
- """
31
1
 
32
2
  # Imports
33
3
  import os
@@ -1,39 +1,37 @@
1
-
2
- # Imports
3
- from beet import Advancement, Context, Function, ItemModifier, Language, LootTable
4
- from stouputils.decorators import measure_time
5
- from stouputils.io import super_json_dump
6
- from stouputils.parallel import multithreading
7
- from stouputils.print import BLUE, progress
8
-
9
- from .utils import handle_file, lang
10
-
11
-
12
- # Main entry point
13
- @measure_time(progress, message="Execution time of 'stewbeet.plugins.auto.lang_file'")
14
- def beet_default(ctx: Context):
15
- """ Main entry point for the lang file plugin.
16
- This plugin handles language file generation for the datapack.
17
-
18
- Args:
19
- ctx (Context): The beet context.
20
- """
21
- # Get all functions and loot tables
22
- files_to_process: dict[str, Function | LootTable] = {}
23
- files_to_process.update(ctx.data.functions)
24
- files_to_process.update(ctx.data.loot_tables)
25
- files_to_process.update(ctx.data.item_modifiers)
26
- files_to_process.update(ctx.data.advancements)
27
-
28
- # Process all files
29
- args: list[tuple[Context, str, Function | LootTable | ItemModifier, Advancement]] = [
30
- (ctx, file, content) for (file, content) in files_to_process.items()
31
- if True
32
- ]
33
- multithreading(handle_file, args, use_starmap=True, desc="Generating lang file", max_workers=min(32, len(args)), color=BLUE)
34
-
35
- # Update the lang file
36
- lang.update(ctx.assets.languages.get("minecraft:en_us", Language()).data)
37
- ctx.assets.languages["minecraft:en_us"] = Language(super_json_dump(lang))
38
- pass
39
-
1
+
2
+ # Imports
3
+ from beet import Context, Language, TextFileBase
4
+ from stouputils.decorators import measure_time
5
+ from stouputils.io import super_json_dump
6
+ from stouputils.parallel import multithreading
7
+ from stouputils.print import BLUE, progress
8
+
9
+ from .utils import handle_file, lang
10
+
11
+
12
+ # Main entry point
13
+ @measure_time(progress, message="Execution time of 'stewbeet.plugins.auto.lang_file'")
14
+ def beet_default(ctx: Context):
15
+ """ Main entry point for the lang file plugin.
16
+ This plugin handles language file generation for the datapack.
17
+
18
+ Args:
19
+ ctx (Context): The beet context.
20
+ """
21
+ # Get all functions and loot tables
22
+ files_to_process: dict[str, TextFileBase] = {}
23
+ files_to_process.update(ctx.data.loot_tables) # Idk why, but this is needed to ensure loot tables are processed
24
+ files_to_process.update(dict(ctx.data.all()))
25
+
26
+ # Process all files
27
+ args: list[tuple[Context, str, TextFileBase]] = [
28
+ (ctx, content) for content in files_to_process.values()
29
+ if isinstance(content, TextFileBase)
30
+ ]
31
+ multithreading(handle_file, args, use_starmap=True, desc="Generating lang file", max_workers=min(32, len(args)), color=BLUE)
32
+
33
+ # Update the lang file
34
+ lang.update(ctx.assets.languages.get("minecraft:en_us", Language()).data)
35
+ ctx.assets.languages["minecraft:en_us"] = Language(super_json_dump(lang))
36
+ pass
37
+
@@ -2,7 +2,7 @@
2
2
  # Imports
3
3
  import re
4
4
 
5
- from beet import Advancement, Context, Function, ItemModifier, LootTable
5
+ from beet import Context, TextFileBase
6
6
  from stouputils.decorators import simple_cache
7
7
 
8
8
  # Prepare lang dictionary and lang_format function
@@ -55,22 +55,20 @@ def lang_format(ctx: Context, text: str) -> tuple[str, str]:
55
55
  return key, re.sub(r"[._]", "", alpha_num)
56
56
 
57
57
 
58
- def handle_file(ctx: Context, file: str, content: Function | LootTable | ItemModifier | Advancement) -> None:
58
+ def handle_file(ctx: Context, content: TextFileBase) -> None:
59
59
  """ Process a file to extract and replace text with lang keys.
60
60
 
61
61
  Args:
62
- ctx (Context): The context containing project information.
63
- file (str): The path to the file being processed.
64
- content (Function | LootTable): The content of the file to process.
62
+ ctx (Context): The context containing project information.
63
+ content (TextFileBase): The content of the file to process.
65
64
 
66
65
  Returns:
67
66
  None: The function modifies the content in place.
68
67
  """
69
68
  # Read content from supported beet types
70
69
  # Function, LootTable, ItemModifier or Advancement
71
- if isinstance(content, Function) or isinstance(content, LootTable) \
72
- or isinstance(content, ItemModifier) or isinstance(content, Advancement):
73
- string: str = content.text
70
+ if isinstance(content, TextFileBase):
71
+ string: str = str(content.text)
74
72
  else:
75
73
  raise ValueError(f"Unsupported content type: {type(content)}")
76
74
 
@@ -97,13 +95,7 @@ def handle_file(ctx: Context, file: str, content: Function | LootTable | ItemMod
97
95
  new_fragment: str = f'{quote}translate{quote}: {quote}{key_for_lang}{quote}'
98
96
  string = string[:start] + new_fragment + string[end:]
99
97
 
100
- # Write the new content back to the appropriate context data
101
- if isinstance(content, Function):
102
- ctx.data.functions[file] = Function(string)
103
- elif isinstance(content, LootTable):
104
- ctx.data.loot_tables[file] = LootTable(string)
105
- elif isinstance(content, ItemModifier):
106
- ctx.data.item_modifiers[file] = ItemModifier(string)
107
- elif isinstance(content, Advancement):
108
- ctx.data.advancements[file] = Advancement(string)
98
+ # Update the content
99
+ if string != str(content.text):
100
+ content.text = string
109
101
 
@@ -70,10 +70,9 @@ def _copy_datapacks(output_path: str, project_name_simple: str, libs_folder: str
70
70
 
71
71
  if os.path.exists(main_datapack):
72
72
  for dest in destinations:
73
- os.makedirs(dest, exist_ok=True)
74
73
  dest_file = relative_path(f"{dest}/{os.path.basename(main_datapack)}")
75
- _copy_with_retry(main_datapack, dest_file)
76
- info(f"Copied normal datapack to: '{dest_file}'")
74
+ if _copy_with_retry(main_datapack, dest_file):
75
+ info(f"Copied normal datapack to: '{dest_file}'")
77
76
 
78
77
  # Copy all library datapacks
79
78
  if libs_folder:
@@ -83,10 +82,9 @@ def _copy_datapacks(output_path: str, project_name_simple: str, libs_folder: str
83
82
  if lib_zip.endswith('.zip'):
84
83
  lib_zip_path = relative_path(f"{libs_datapack_path}/{lib_zip}")
85
84
  for dest in destinations:
86
- os.makedirs(dest, exist_ok=True)
87
85
  dest_file = relative_path(f"{dest}/{lib_zip}")
88
- _copy_with_retry(lib_zip_path, dest_file)
89
- info(f"Copied library datapack to: '{dest_file}'")
86
+ if _copy_with_retry(lib_zip_path, dest_file):
87
+ info(f"Copied library datapack to: '{dest_file}'")
90
88
 
91
89
 
92
90
  def _copy_resource_packs(output_path: str, project_name_simple: str, destinations: list[str]) -> None:
@@ -105,14 +103,13 @@ def _copy_resource_packs(output_path: str, project_name_simple: str, destination
105
103
 
106
104
  if os.path.exists(resource_pack_to_copy):
107
105
  for dest in destinations:
108
- os.makedirs(dest, exist_ok=True)
109
106
  # Use original name (without _with_libs suffix) for the destination
110
107
  with_libs = "_with_libs" if resource_pack_to_copy == merged_resource_pack else ""
111
108
  dest_name = f"{project_name_simple}_resource_pack{with_libs}.zip"
112
109
  dest_file = relative_path(f"{dest}/{dest_name}")
113
- _copy_with_retry(resource_pack_to_copy, dest_file)
114
- pack_type = "merged" if resource_pack_to_copy == merged_resource_pack else "normal"
115
- info(f"Copied {pack_type} resource pack to: '{dest_file}'")
110
+ if _copy_with_retry(resource_pack_to_copy, dest_file):
111
+ pack_type = "merged" if resource_pack_to_copy == merged_resource_pack else "normal"
112
+ info(f"Copied {pack_type} resource pack to: '{dest_file}'")
116
113
 
117
114
 
118
115
  def _copy_official_libs(datapack_destinations: list[str]) -> None:
@@ -136,13 +133,12 @@ def _copy_official_libs(datapack_destinations: list[str]) -> None:
136
133
  lib_zip_path = relative_path(f"{official_datapack_path}/{lib_zip}")
137
134
  if os.path.exists(lib_zip_path):
138
135
  for dest in datapack_destinations:
139
- os.makedirs(dest, exist_ok=True)
140
136
  dest_file = relative_path(f"{dest}/{lib_zip}")
141
- _copy_with_retry(lib_zip_path, dest_file)
142
- info(f"Copied official library to: '{dest_file}'")
137
+ if _copy_with_retry(lib_zip_path, dest_file):
138
+ info(f"Copied official library to: '{dest_file}'")
143
139
 
144
140
 
145
- def _copy_with_retry(src: str, dst: str, max_retries: int = 10, delay: float = 1.0) -> None:
141
+ def _copy_with_retry(src: str, dst: str, max_retries: int = 10, delay: float = 1.0) -> bool:
146
142
  """ Copy a file with retry logic to handle permission errors.
147
143
 
148
144
  Args:
@@ -150,6 +146,8 @@ def _copy_with_retry(src: str, dst: str, max_retries: int = 10, delay: float = 1
150
146
  dst (str): Destination file path.
151
147
  max_retries (int): Maximum number of retry attempts.
152
148
  delay (float): Delay in seconds between retries.
149
+ Returns:
150
+ bool: True if the copy was successful, False if it failed after all retries.
153
151
  """
154
152
  # Delete the destination file if it exists (optional)
155
153
  if os.path.exists(dst):
@@ -159,16 +157,20 @@ def _copy_with_retry(src: str, dst: str, max_retries: int = 10, delay: float = 1
159
157
  pass
160
158
 
161
159
  # Ensure the destination directory exists
162
- os.makedirs(os.path.dirname(dst), exist_ok=True)
160
+ dest_dir = os.path.dirname(dst)
161
+ if not os.path.exists(dest_dir):
162
+ warning(f"Destination directory '{dest_dir}' does not exist. Cannot copy file '{src}'.")
163
+ return False
163
164
 
164
165
  # Attempt to copy the file with retries
165
166
  for attempt in range(max_retries):
166
167
  try:
167
168
  shutil.copy(src, dst)
168
- return
169
+ return True
169
170
  except PermissionError as e:
170
171
  if attempt == max_retries - 1:
171
172
  raise e
172
173
  warning(f"Failed to copy '{src}' the destinations ({e.__class__.__name__}). Retrying in {delay} seconds...")
173
174
  time.sleep(delay)
175
+ return False # If all retries failed, return False
174
176
 
@@ -401,18 +401,28 @@ execute as @e[tag={ns}.custom_block,dx=0,dy=0,dz=0] at @s run function {ns}:cust
401
401
  )
402
402
  adv["rewards"]["function"] = f"{ns}:custom_blocks/_player_head/search_{item}"
403
403
  adv_obj = Advancement(adv)
404
- adv_obj.encoder = super_json_dump
404
+ adv_obj.encoder = lambda x: super_json_dump(x, max_level=-1)
405
405
  ctx.data[ns].advancements[f"custom_block_head/{item}"] = adv_obj
406
406
 
407
- # Make search function
407
+ ## Make search function
408
408
  content = "# Search where the head has been placed\n"
409
409
  mid_x, mid_y, mid_z = [x // 2 for x in CUSTOM_BLOCK_HEAD_CUBE_RADIUS]
410
- content += f"""
411
- for x in range({-mid_x}, {mid_x + 1}):
412
- for y in range({-mid_y}, {mid_y + 1}):
413
- for z in range({-mid_z}, {mid_z + 1}):
414
- execute positioned ~x ~y ~z if data block ~ ~ ~ components.\"minecraft:custom_data\".{ns}.{item} run function {ns}:custom_blocks/{item}/place_main
415
- """
410
+
411
+ # Generate main search function that calls x-loop
412
+ for x in range(-mid_x, mid_x + 1):
413
+ content += f"execute positioned ~{x} ~ ~ run function {ns}:custom_blocks/_player_head/search_{item}_y\n"
416
414
  content += f"\n# Advancement\nadvancement revoke @s only {ns}:custom_block_head/{item}\n\n"
417
415
  write_function(f"{ns}:custom_blocks/_player_head/search_{item}", content)
418
416
 
417
+ # Generate y-loop function
418
+ content_y = "# Search y coordinates\n"
419
+ for y in range(-mid_y, mid_y + 1):
420
+ content_y += f"execute positioned ~ ~{y} ~ run function {ns}:custom_blocks/_player_head/search_{item}_z\n"
421
+ write_function(f"{ns}:custom_blocks/_player_head/search_{item}_y", content_y)
422
+
423
+ # Generate z-loop function
424
+ content_z = "# Search z coordinates\n"
425
+ for z in range(-mid_z, mid_z + 1):
426
+ content_z += f"execute positioned ~ ~ ~{z} if data block ~ ~ ~ components.\"minecraft:custom_data\".{ns}.{item} run function {ns}:custom_blocks/{item}/place_main\n"
427
+ write_function(f"{ns}:custom_blocks/_player_head/search_{item}_z", content_z)
428
+
@@ -102,7 +102,7 @@ def beet_default(ctx: Context) -> None:
102
102
 
103
103
  # Get all dependencies (official and custom)
104
104
  dependencies: list[tuple[str, dict]] = [(lib_ns, data) for lib_ns, data in OFFICIAL_LIBS.items() if data["is_used"]]
105
- load_dependencies: JsonDict = ctx.meta.get("load_dependencies", {})
105
+ load_dependencies: JsonDict = ctx.meta.get("stewbeet", {}).get("load_dependencies", {})
106
106
  if load_dependencies:
107
107
  dependencies += list(load_dependencies.items())
108
108
  # Setup Lantern Load
@@ -9,10 +9,9 @@ from beet import Font, Texture
9
9
  from beet.core.utils import JsonDict, TextComponent
10
10
  from PIL import Image
11
11
  from stouputils.collections import unique_list
12
- from stouputils.decorators import measure_time
13
12
  from stouputils.io import relative_path, super_json_dump, super_open
14
13
  from stouputils.parallel import colored_for_loop
15
- from stouputils.print import debug, error, info, suggestion, warning
14
+ from stouputils.print import debug, error, suggestion, warning
16
15
 
17
16
  from ...core.__memory__ import Mem
18
17
  from ...core.constants import (
@@ -3,7 +3,7 @@
3
3
  import os
4
4
  from pathlib import Path
5
5
 
6
- from beet import Context, Pack
6
+ from beet import Context, Pack, PngFile
7
7
  from beet.core.utils import JsonDict, TextComponent
8
8
  from box import Box
9
9
  from stouputils import relative_path
@@ -12,11 +12,11 @@ from stouputils.io import super_json_dump
12
12
  from stouputils.print import warning
13
13
 
14
14
  from ...core import Mem
15
- from .source_lore_font import make_source_lore_font
15
+ from .source_lore_font import find_pack_png, make_source_lore_font
16
16
 
17
17
 
18
18
  # Main entry point
19
- @measure_time(message="Total execution time")
19
+ @measure_time(message="Total execution time", is_generator=True)
20
20
  def beet_default(ctx: Context):
21
21
 
22
22
  # Assertions
@@ -90,7 +90,12 @@ def beet_default(ctx: Context):
90
90
  new_path = Path(textures_folder) / new_name
91
91
  if old_path.exists() and not new_path.exists():
92
92
  os.rename(old_path, new_path)
93
- warning(f"Renamed texture {file} to {new_name}")
93
+ warning(f"Renamed texture '{file}' to '{new_name}'")
94
+
95
+ # Add the pack icon to the output directory for datapack and resource pack
96
+ pack_icon = find_pack_png()
97
+ if pack_icon:
98
+ Mem.ctx.data.extra["pack.png"] = Mem.ctx.assets.extra["pack.png"] = PngFile(source_path=pack_icon)
94
99
 
95
100
  # Yield message to indicate successful build
96
101
  yield
@@ -279,7 +279,9 @@ class AutoModel:
279
279
  for texture in content["textures"].values():
280
280
  if texture.startswith("minecraft:"):
281
281
  continue
282
- self.used_textures.add(texture) # Copy used textures
282
+ self.used_textures.add(texture)
283
+
284
+ # Copy used textures
283
285
  if content.get("textures"):
284
286
  for texture in content["textures"].values():
285
287
  # Ignore if minecraft namespace
@@ -111,18 +111,18 @@ def beet_default(ctx: Context) -> None:
111
111
 
112
112
  # Force the use of "item_name" key for every item
113
113
  if not data.get("item_name"):
114
- errors.append(f"'item_name' key missing for '{item}', should be a dict or a list (SNBT), ex: {{\"text\":\"This is an Item Name\"}} or [\"This is an Item Name\"]")
114
+ errors.append(f"'item_name' key missing for '{item}', should be a Text Component, ex: {{\"text\":\"This is an Item Name\"}} or [\"This is an Item Name\"]")
115
115
  elif not isinstance(data["item_name"], dict | list | str):
116
- errors.append(f"'item_name' key should be a dict or a list (SNBT) for '{item}'")
116
+ errors.append(f"'item_name' key should be a Text Component for '{item}', got '{data['item_name']}'")
117
117
 
118
118
  # Force the use of "lore" key to be in a correct format
119
119
  if data.get("lore"):
120
120
  if not isinstance(data["lore"], list):
121
- errors.append(f"'lore' key should be a list for '{item}'")
121
+ errors.append(f"'lore' key should be a list for '{item}', got {data['lore']}")
122
122
  else:
123
123
  for i, line in enumerate(data["lore"]):
124
124
  if not isinstance(line, dict | list | str):
125
- errors.append(f"Line #{i} in 'lore' key should be a dict or a list (SNBT) for '{item}', ex: {{\"text\":\"This is a lore line\"}} or [\"This is a lore line\"]")
125
+ errors.append(f"Line #{i} in 'lore' key should be a Text Component for '{item}', ex: {{\"text\":\"This is a lore line\"}} or [\"This is a lore line\"]")
126
126
  else:
127
127
  # Verify format {"text":"..."} or "..."
128
128
  line = str(line)
@@ -210,7 +210,7 @@ def beet_default(ctx: Context) -> None:
210
210
 
211
211
  # Log errors if any
212
212
  if errors:
213
- error("Errors found in the definitions during verification:\n" + "\n".join(errors))
213
+ error("Errors found in the definitions during verification:\n- " + "\n- ".join(errors))
214
214
  else:
215
215
  info("No errors found in the definitions during verification")
216
216
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes