mc-shell 0.7.0__tar.gz → 0.7.2__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.
Files changed (217) hide show
  1. {mc_shell-0.7.0 → mc_shell-0.7.2}/PKG-INFO +2 -3
  2. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/__init__.py +360 -72
  3. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/constants.py +11 -9
  4. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/index.html +2 -2
  5. mc_shell-0.7.0/mcshell/data/app/mced.484d99b8.js → mc_shell-0.7.2/mcshell/data/app/mced.3d4a5c3d.js +127 -86
  6. mc_shell-0.7.0/mcshell/data/app/mced.484d99b8.js.map → mc_shell-0.7.2/mcshell/data/app/mced.3d4a5c3d.js.map +1 -1
  7. mc_shell-0.7.2/mcshell/data/app/mced.3f8a9cca.css +2 -0
  8. mc_shell-0.7.2/mcshell/data/app/mced.3f8a9cca.css.map +1 -0
  9. mc_shell-0.7.2/mcshell/data/app/toolbox.193e3fba.xml +503 -0
  10. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/materials/colourables.json +154 -154
  11. mc_shell-0.7.2/mcshell/data/materials/entity_overrides.json +4 -0
  12. mc_shell-0.7.2/mcshell/data/materials/item_id_map.pkl +0 -0
  13. mc_shell-0.7.2/mcshell/data/materials/materials.pkl +0 -0
  14. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/materials/pickers.json +184 -0
  15. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/materials/singles.json +2 -171
  16. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/powers/stdlib.json +2669 -1
  17. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/toolbox_template.xml +1 -1
  18. mc_shell-0.7.2/mcshell/digitalgeometryactions.py +60 -0
  19. mc_shell-0.7.2/mcshell/digitalsetactions.py +243 -0
  20. mc_shell-0.7.0/mcshell/mceventactions.py → mc_shell-0.7.2/mcshell/eventactions.py +0 -7
  21. mc_shell-0.7.2/mcshell/mcactions.py +117 -0
  22. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcactions_base.py +41 -0
  23. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcblockly.py +140 -123
  24. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcclient.py +48 -27
  25. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcplayer.py +27 -16
  26. mc_shell-0.7.2/mcshell/mcscraper.py +300 -0
  27. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcserver.py +2 -2
  28. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcturtle.py +63 -18
  29. mc_shell-0.7.2/mcshell/playeractions.py +75 -0
  30. mc_shell-0.7.2/mcshell/pyncraftcactions.py +148 -0
  31. mc_shell-0.7.2/mcshell/qturtleactions.py +122 -0
  32. mc_shell-0.7.2/mcshell/registry_builder.py +619 -0
  33. mc_shell-0.7.2/mcshell/serveractions.py +249 -0
  34. {mc_shell-0.7.0 → mc_shell-0.7.2}/pyproject.toml +2 -3
  35. mc_shell-0.7.0/mcshell/data/app/mced.55f94dd4.css +0 -2
  36. mc_shell-0.7.0/mcshell/data/app/mced.55f94dd4.css.map +0 -1
  37. mc_shell-0.7.0/mcshell/data/app/toolbox.48fd1f79.xml +0 -758
  38. mc_shell-0.7.0/mcshell/data/materials/entity_overrides.json +0 -4
  39. mc_shell-0.7.0/mcshell/data/materials/materials.pkl +0 -0
  40. mc_shell-0.7.0/mcshell/mcactions.py +0 -454
  41. mc_shell-0.7.0/mcshell/mcscraper.py +0 -238
  42. mc_shell-0.7.0/mcshell/pyncactions.py +0 -262
  43. mc_shell-0.7.0/mcshell/serveractions.py +0 -204
  44. {mc_shell-0.7.0 → mc_shell-0.7.2}/LICENSE +0 -0
  45. {mc_shell-0.7.0 → mc_shell-0.7.2}/README.md +0 -0
  46. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/Matrix3.py +0 -0
  47. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/Vec3.py +0 -0
  48. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/blueprints/control_api.py +0 -0
  49. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/blueprints/ipython_api.py +0 -0
  50. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/blueprints/powers_api.py +0 -0
  51. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/FruitJuice-0.3.0.jar +0 -0
  52. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/FruitJuice-0.4.0.jar +0 -0
  53. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/FruitJuice-0.4.1.jar +0 -0
  54. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/control.a8439284.css +0 -0
  55. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/control.a8439284.css.map +0 -0
  56. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/control.b03e9afc.js +0 -0
  57. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/control.b03e9afc.js.map +0 -0
  58. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/control.html +0 -0
  59. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/mced.a4de160c.js +0 -0
  60. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/mced.a4de160c.js.map +0 -0
  61. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/mced.efd4d8e7.css +0 -0
  62. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/mced.efd4d8e7.css.map +0 -0
  63. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/control_layout.json +0 -0
  64. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/flat_world/data/minecraft/dimension/overworld.json +0 -0
  65. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/flat_world/data/minecraft/worldgen/biome/the_void.json +0 -0
  66. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/flat_world/pack.mcmeta +0 -0
  67. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/void_world/data/minecraft/dimension/overworld.json +0 -0
  68. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/void_world/data/minecraft/functions/init.mcfunction +0 -0
  69. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/void_world/data/minecraft/tags/functions/load.json +0 -0
  70. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/void_world/data/minecraft/worldgen/biome/the_void.json +0 -0
  71. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/void_world/pack.mcmeta +0 -0
  72. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/doc/command_docs.pkl +0 -0
  73. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/entities/entity_id_map.pkl +0 -0
  74. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/entities/generate_entity_blocks.mjs +0 -0
  75. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/entities/pickers.json +0 -0
  76. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/materials/generate_material_blocks.mjs +0 -0
  77. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/materials/mcblocks.csv +0 -0
  78. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/paper-global-template.yaml +0 -0
  79. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/%3F.pkl +0 -0
  80. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/Commands.pkl +0 -0
  81. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/EntityType.java.pkl +0 -0
  82. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/Material.html.pkl +0 -0
  83. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/ability.pkl +0 -0
  84. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/advancement.pkl +0 -0
  85. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/alwaysday.pkl +0 -0
  86. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/attribute.pkl +0 -0
  87. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/ban-ip.pkl +0 -0
  88. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/ban.pkl +0 -0
  89. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/banlist.pkl +0 -0
  90. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/bossbar.pkl +0 -0
  91. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/camera.pkl +0 -0
  92. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/camerashake.pkl +0 -0
  93. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/changesetting.pkl +0 -0
  94. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/clear.pkl +0 -0
  95. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/clearspawnpoint.pkl +0 -0
  96. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/clone.pkl +0 -0
  97. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/connect.pkl +0 -0
  98. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/damage.pkl +0 -0
  99. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/data.pkl +0 -0
  100. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/datapack.pkl +0 -0
  101. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/daylock.pkl +0 -0
  102. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/debug.pkl +0 -0
  103. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/dedicatedwsserver.pkl +0 -0
  104. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/defaultgamemode.pkl +0 -0
  105. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/deop.pkl +0 -0
  106. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/dialogue.pkl +0 -0
  107. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/difficulty.pkl +0 -0
  108. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/effect.pkl +0 -0
  109. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/enchant.pkl +0 -0
  110. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/event.pkl +0 -0
  111. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/execute.pkl +0 -0
  112. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/experience.pkl +0 -0
  113. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/fill.pkl +0 -0
  114. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/fillbiome.pkl +0 -0
  115. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/fog.pkl +0 -0
  116. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/forceload.pkl +0 -0
  117. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/function.pkl +0 -0
  118. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/gamemode.pkl +0 -0
  119. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/gamerule.pkl +0 -0
  120. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/gametest.pkl +0 -0
  121. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/give.pkl +0 -0
  122. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/help.pkl +0 -0
  123. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/immutableworld.pkl +0 -0
  124. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/item.pkl +0 -0
  125. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/jfr.pkl +0 -0
  126. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/kick.pkl +0 -0
  127. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/kill.pkl +0 -0
  128. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/list.pkl +0 -0
  129. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/locate.pkl +0 -0
  130. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/loot.pkl +0 -0
  131. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/me.pkl +0 -0
  132. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/mobevent.pkl +0 -0
  133. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/msg.pkl +0 -0
  134. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/music.pkl +0 -0
  135. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/op.pkl +0 -0
  136. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/ops.pkl +0 -0
  137. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/pardon-ip.pkl +0 -0
  138. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/pardon.pkl +0 -0
  139. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/particle.pkl +0 -0
  140. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/perf.pkl +0 -0
  141. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/permission.pkl +0 -0
  142. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/place_(Java_Edition).pkl +0 -0
  143. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/playanimation.pkl +0 -0
  144. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/playsound.pkl +0 -0
  145. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/publish.pkl +0 -0
  146. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/random.pkl +0 -0
  147. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/recipe.pkl +0 -0
  148. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/reload.pkl +0 -0
  149. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/remove.pkl +0 -0
  150. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/replaceitem.pkl +0 -0
  151. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/return.pkl +0 -0
  152. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/ride.pkl +0 -0
  153. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/save-all.pkl +0 -0
  154. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/save-off.pkl +0 -0
  155. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/save-on.pkl +0 -0
  156. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/save.pkl +0 -0
  157. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/say.pkl +0 -0
  158. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/schedule.pkl +0 -0
  159. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/scoreboard.pkl +0 -0
  160. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/script.pkl +0 -0
  161. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/scriptevent.pkl +0 -0
  162. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/seed.pkl +0 -0
  163. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/setblock.pkl +0 -0
  164. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/setidletimeout.pkl +0 -0
  165. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/setmaxplayers.pkl +0 -0
  166. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/setworldspawn.pkl +0 -0
  167. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/spawnpoint.pkl +0 -0
  168. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/spectate.pkl +0 -0
  169. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/spreadplayers.pkl +0 -0
  170. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/stop.pkl +0 -0
  171. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/stopsound.pkl +0 -0
  172. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/structure.pkl +0 -0
  173. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/summon.pkl +0 -0
  174. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tag.pkl +0 -0
  175. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/team.pkl +0 -0
  176. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/teammsg.pkl +0 -0
  177. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/teleport.pkl +0 -0
  178. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tell.pkl +0 -0
  179. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tellraw.pkl +0 -0
  180. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/testfor.pkl +0 -0
  181. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/testforblock.pkl +0 -0
  182. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/testforblocks.pkl +0 -0
  183. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tickingarea.pkl +0 -0
  184. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/time.pkl +0 -0
  185. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/title.pkl +0 -0
  186. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/titleraw.pkl +0 -0
  187. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tm.pkl +0 -0
  188. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/toggledownfall.pkl +0 -0
  189. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tp.pkl +0 -0
  190. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/transferserver.pkl +0 -0
  191. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/trigger.pkl +0 -0
  192. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/volumearea.pkl +0 -0
  193. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/w.pkl +0 -0
  194. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/wb.pkl +0 -0
  195. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/weather.pkl +0 -0
  196. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/whitelist.pkl +0 -0
  197. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/worldborder.pkl +0 -0
  198. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/worldbuilder.pkl +0 -0
  199. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/wsserver.pkl +0 -0
  200. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/xp.pkl +0 -0
  201. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcexperience_base.py +0 -0
  202. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mclsystem.py +0 -0
  203. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcrepo.py +0 -0
  204. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcshell.py +0 -0
  205. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcvoxel.py +0 -0
  206. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcvoxel_original.py +0 -0
  207. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/ppdownloader.py +0 -0
  208. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/ppmanager.py +0 -0
  209. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/__init__.py +0 -0
  210. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/block.py +0 -0
  211. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/connection.py +0 -0
  212. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/entity.py +0 -0
  213. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/event.py +0 -0
  214. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/logger.py +0 -0
  215. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/minecraft.py +0 -0
  216. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/util.py +0 -0
  217. {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/vec3.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mc-shell
3
- Version: 0.7.0
3
+ Version: 0.7.2
4
4
  Summary: An interactive shell and editor for controlling Minecraft servers and creating powers.
5
5
  License-File: LICENSE
6
6
  Author: Jeff
@@ -12,7 +12,6 @@ Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
13
  Classifier: Programming Language :: Python :: 3.13
14
14
  Classifier: Programming Language :: Python :: 3.14
15
- Requires-Dist: aio-mc-rcon
16
15
  Requires-Dist: beautifulsoup4
17
16
  Requires-Dist: blockapily
18
17
  Requires-Dist: click
@@ -21,13 +20,13 @@ Requires-Dist: flask
21
20
  Requires-Dist: flask-cors
22
21
  Requires-Dist: flask-socketio
23
22
  Requires-Dist: ipython
23
+ Requires-Dist: mctools (>=1.4.1,<2.0.0)
24
24
  Requires-Dist: numpy
25
25
  Requires-Dist: pexpect
26
26
  Requires-Dist: pickleshare
27
27
  Requires-Dist: pytest (>=9.0.2,<10.0.0)
28
28
  Requires-Dist: python-socketio[client]
29
29
  Requires-Dist: pyyaml (>=6.0.2,<7.0.0)
30
- Requires-Dist: rcon
31
30
  Requires-Dist: requests
32
31
  Requires-Dist: rich
33
32
  Requires-Dist: voxelmap (>=5.1.1,<6.0.0)
@@ -18,6 +18,7 @@ from mcshell.ppmanager import *
18
18
  from mcshell.ppdownloader import *
19
19
 
20
20
  from mcshell.mcserver import stop_app_server
21
+ from mcshell.mcplayer import MCPlayer
21
22
 
22
23
  import atexit
23
24
 
@@ -52,6 +53,7 @@ class MCShell(Magics):
52
53
 
53
54
  self.active_paper_server: Optional[PaperServerManager ,None ] = None
54
55
 
56
+
55
57
  def _complete_world_command(self, ipyshell, event):
56
58
  ipyshell.user_ns.update(dict(rcon_event=event))
57
59
  text = event.symbol
@@ -146,7 +148,9 @@ class MCShell(Magics):
146
148
  print("\nWorld creation cancelled.")
147
149
  return
148
150
 
149
- self.server_data = {"host": '127.0.0.1','port':MC_SERVER_PORT, "rcon_port": MC_RCON_PORT, "password": password, "fj_port":FJ_PLUGIN_PORT} # Port can be dynamic if needed
151
+ self.server_data['password'] = password
152
+
153
+ # self.server_data = {"host": '127.0.0.1','port':MC_SERVER_PORT, "rcon_port": MC_RCON_PORT, "password": password, "fj_port":FJ_PLUGIN_PORT} # Port can be dynamic if needed
150
154
 
151
155
  print("Input the ports for the server, rcon and plugin. These only need to be changed if you are running more than one mc-shell!")
152
156
  try:
@@ -154,13 +158,22 @@ class MCShell(Magics):
154
158
  resp_port = Prompt.ask('Server Port:', default=str(self.server_data['port']))
155
159
  resp_rcon = Prompt.ask('RCON Port:', default=str(self.server_data['rcon_port']))
156
160
  resp_fj = Prompt.ask('FruitJuice Port:', default=str(self.server_data['fj_port']))
161
+ resp_app = Prompt.ask('Application Port:', default=str(self.server_data['app_port']))
157
162
 
158
163
  # Robust casting logic
159
164
  ports = {
160
165
  'port': int(resp_port) if resp_port else self.server_data['port'],
161
166
  'rcon_port': int(resp_rcon) if resp_rcon else self.server_data['rcon_port'],
162
- 'fj_port': int(resp_fj) if resp_fj else self.server_data['fj_port']
167
+ 'fj_port': int(resp_fj) if resp_fj else self.server_data['fj_port'],
168
+ 'app_port': int(resp_app) if resp_app else self.server_data['app_port']
163
169
  }
170
+
171
+
172
+ self.server_data['port'] = ports['port']
173
+ self.server_data['rcon_port'] = ports['rcon_port']
174
+ self.server_data['fj_port'] = ports['fj_port']
175
+ self.server_data['app_port'] = ports['app_port']
176
+
164
177
  except (EOFError, KeyboardInterrupt):
165
178
  print("\nWorld creation cancelled.")
166
179
  return
@@ -209,7 +222,8 @@ class MCShell(Magics):
209
222
  "server-port": self.server_data.get('port', MC_SERVER_PORT),
210
223
  "query.port": self.server_data.get('port', MC_SERVER_PORT),
211
224
  "rcon.port": self.server_data.get('rcon_port', MC_RCON_PORT),
212
- "rcon.password": self.server_data.get('password', 'minecraft'),
225
+ "app.port": self.server_data.get('app_port', MC_APP_PORT),
226
+ "rcon.password": self.server_data.get('password'),
213
227
  "enable-command-block":'true',
214
228
  },
215
229
  "FruitJuice" : {
@@ -325,6 +339,8 @@ class MCShell(Magics):
325
339
  with creds_path.open('r') as f:
326
340
  self.server_data = json.load(f)
327
341
 
342
+ if not 'app_port' in list(self.server_data.keys()):
343
+ self.server_data['app_port'] = 5001
328
344
  # start the app server
329
345
  self.ip.run_line_magic('mc_start_app','')
330
346
 
@@ -494,7 +510,7 @@ class MCShell(Magics):
494
510
  except ConnectionRefusedError as e:
495
511
  print("[red bold]Unable to send command. Is the server running?[/]")
496
512
  pprint(self.server_data)
497
- except (WrongPassword, IncorrectPasswordError) as e:
513
+ except RCONAuthenticationError as e:
498
514
  print("[red bold]The password is wrong. Use %mc_login reset[/]")
499
515
 
500
516
  def _get_client(self):
@@ -506,41 +522,105 @@ class MCShell(Magics):
506
522
  def _help(self, *args):
507
523
  return self._send('help', *args)
508
524
  def _run(self, *args):
509
- return self._send('run',*args)
525
+ return self._send('run',*args)
510
526
  def _data(self, *args):
511
527
  return self._send('data',*args)
512
528
 
529
+ # @property
530
+ # def commands(self):
531
+ # _rcon_commands = {}
532
+ # if not self.rcon_commands:
533
+ # try:
534
+ # _help_text = self._help()
535
+ # except:
536
+ # return _rcon_commands
537
+ #
538
+ # _help_data = list(filter(lambda x: x != '', map(lambda x: x.split(' '), _help_text.split('/'))))[1:]
539
+ # for _help_datum in _help_data:
540
+ # _cmd = _help_datum[0]
541
+ # if 'minecraft:' in _cmd:
542
+ # _cmd = _cmd.split(':')[1]
543
+ # try:
544
+ # _cmd_data = self._help(_cmd)
545
+ # except:
546
+ # return
547
+ # if not _cmd_data:
548
+ # # found a shortcut command like xp -> experience
549
+ # continue
550
+ # _cmd_data = list(map(lambda x:x.split()[1:],_cmd_data.split('/')))
551
+ # _sub_cmd_data = {}
552
+ # for _sub_cmd_datum in _cmd_data[1:]:
553
+ # if not _sub_cmd_datum[0][0] in ('<','[','('):
554
+ # _sub_cmd_data.update({_sub_cmd_datum[0]: _sub_cmd_datum[1:]})
555
+ # else:
556
+ # # TODO what about commands without sub-commands?
557
+ # _sub_cmd_data.update({' ': _sub_cmd_datum})
558
+ # _rcon_commands.update({_cmd.replace('-','_'): _sub_cmd_data})
559
+ # self.rcon_commands = _rcon_commands
560
+ # return self.rcon_commands
561
+
513
562
  @property
514
563
  def commands(self):
515
- _rcon_commands = {}
564
+ """
565
+ Builds a unique, deduplicated command and subcommand registry.
566
+ Deduplicates sub-items like gamerules (e.g., 'spawn_mobs' vs 'minecraft:spawn_mobs').
567
+ """
516
568
  if not self.rcon_commands:
569
+ _rcon_commands = {}
517
570
  try:
518
- _help_text = self._help()
571
+ _help_text = self._help() # Stripped by MCClient
519
572
  except:
520
- return _rcon_commands
573
+ return {}
574
+
575
+ if not _help_text:
576
+ return {}
577
+
578
+ seen_base_cmds = set()
579
+ _help_data = list(filter(None, _help_text.split('/')))
580
+
581
+ for entry in _help_data:
582
+ parts = entry.split()
583
+ if not parts or parts[0] in ('?', 'bukkit:?'):
584
+ continue
585
+
586
+ raw_cmd = parts[0]
587
+ base_cmd = raw_cmd.split(':')[-1]
588
+
589
+ if base_cmd in seen_base_cmds:
590
+ continue
591
+
592
+ seen_base_cmds.add(base_cmd)
593
+ clean_key = raw_cmd.replace('-', '_')
521
594
 
522
- _help_data = list(filter(lambda x: x != '', map(lambda x: x.split(' '), _help_text.split('/'))))[1:]
523
- for _help_datum in _help_data:
524
- _cmd = _help_datum[0]
525
- if 'minecraft:' in _cmd:
526
- _cmd = _cmd.split(':')[1]
527
595
  try:
528
- _cmd_data = self._help(_cmd)
596
+ _cmd_help = self._help(raw_cmd) # Stripped by MCClient
597
+ _help_lines = list(map(lambda x: x.split()[1:], _cmd_help.split('/')))
598
+
599
+ _sub_cmd_data = {}
600
+ seen_sub_items = set() # Track subcommands/gamerules specifically
601
+
602
+ for line_args in _help_lines:
603
+ if not line_args:
604
+ continue
605
+
606
+ arg0 = line_args[0]
607
+ # If it's a literal (not a placeholder like <target>)
608
+ if not arg0.startswith(('<', '[', '(')):
609
+ # Deduplicate sub-item (e.g., minecraft:spawn_mobs -> spawn_mobs)
610
+ clean_sub = arg0.split(':')[-1]
611
+ if clean_sub not in seen_sub_items:
612
+ _sub_cmd_data.update({clean_sub: line_args[1:]})
613
+ seen_sub_items.add(clean_sub)
614
+ else:
615
+ # Catch-all for commands that take direct syntax arguments
616
+ _sub_cmd_data.update({' ': line_args})
617
+
618
+ _rcon_commands.update({clean_key: _sub_cmd_data})
529
619
  except:
530
- return
531
- if not _cmd_data:
532
- # found a shortcut command like xp -> experience
533
620
  continue
534
- _cmd_data = list(map(lambda x:x.split()[1:],_cmd_data.split('/')))
535
- _sub_cmd_data = {}
536
- for _sub_cmd_datum in _cmd_data[1:]:
537
- if not _sub_cmd_datum[0][0] in ('<','[','('):
538
- _sub_cmd_data.update({_sub_cmd_datum[0]: _sub_cmd_datum[1:]})
539
- else:
540
- # TODO what about commands without sub-commands?
541
- _sub_cmd_data.update({' ': _sub_cmd_datum})
542
- _rcon_commands.update({_cmd.replace('-','_'): _sub_cmd_data})
621
+
543
622
  self.rcon_commands = _rcon_commands
623
+
544
624
  return self.rcon_commands
545
625
 
546
626
  @line_magic
@@ -567,56 +647,91 @@ class MCShell(Magics):
567
647
  _mcc = self._get_client()
568
648
  pprint(self.server_data)
569
649
 
570
- @line_magic
571
- def mc_help(self,line):
572
- '''
573
- %mc_help [COMMAND]
574
- '''
575
650
 
651
+ @line_magic
652
+ def mc_help(self, line):
653
+ """
654
+ Sorted, deduplicated help menu.
655
+ Prevents 'minecraft:' clutter and gamerule text-walls.
656
+ """
576
657
  _cmd = []
577
- _doc_line = ''
578
- _doc_url = ''
579
- _doc_code_lines = ''
580
658
  if line:
581
659
  _line_parts = line.split()
582
- if 'minecraft:' in _line_parts[0]:
583
- _line_parts[0] = _line_parts[0].split(':')[1]
584
- _doc_line,_doc_url,_doc_code_lines = self.mc_cmd_docs.get(_line_parts[0],('','',''))
585
- _line_parts[0] = _line_parts[0].replace('_', '-')
586
- _cmd += [' '.join(_line_parts)]
660
+ # Lookup docs by clean name (e.g., 'enchant' even if user types 'minecraft:enchant')
661
+ clean_name = _line_parts[0].split(':')[-1]
662
+ _doc_data = self.mc_cmd_docs.get(clean_name, (None, None, None))
587
663
 
588
- if _doc_line and _doc_url:
589
- print(_doc_line)
590
- print(_doc_url)
591
- print()
664
+ if _doc_data[0]:
665
+ print(f"{_doc_data[0]}\n{_doc_data[1]}\n")
592
666
 
593
- if _doc_code_lines:
594
- for _doc_code_line in _doc_code_lines:
595
- print(_doc_code_line)
596
- else:
597
- _help_text = self._help(*_cmd)
598
- if not _help_text:
599
- print("No help available!")
667
+ if _doc_data[2]:
668
+ for d_line in _doc_data[2]: print(d_line)
600
669
  return
601
- for _help_line in _help_text.split('/')[1:]:
602
- _help_parts = _help_line.split()
603
- _help_parts[0] = _help_parts[0].replace('-','_')
604
- print(f'{" ".join(_help_parts)}')
670
+
671
+ _cmd += [' '.join(_line_parts)]
672
+
673
+ _raw_help = self._help(*_cmd)
674
+ if not _raw_help:
675
+ print("No help available!")
676
+ return
677
+
678
+ _help_text = _raw_help
679
+
680
+ seen_base = set()
681
+ output = []
682
+
683
+ for entry in filter(None, _help_text.split('/')):
684
+ parts = entry.split()
685
+ if not parts or parts[0] in ('?', 'bukkit:?'): continue
686
+
687
+ raw_cmd = parts[0]
688
+ base_name = raw_cmd.split(':')[-1]
689
+
690
+ if base_name in seen_base: continue
691
+ seen_base.add(base_name)
692
+
693
+ # Truncate the massive gamerule ruleset for the general list
694
+ if base_name == "gamerule" and len(entry) > 200:
695
+ entry = f"{raw_cmd} <rule> [<value>]"
696
+
697
+ output.append(entry.replace('-', '_'))
698
+
699
+ # Sort alphabetically for easy scanning
700
+ for line in sorted(output):
701
+ print(line)
605
702
 
606
703
  def _complete_mc_help(self, ipyshell, event):
607
- ipyshell.user_ns.update(dict(rcon_event=event))
608
- text = event.symbol
704
+ """
705
+ Provides deep, deduplicated completion for %mc_help.
706
+ Supports: %mc_help gamerule <TAB> -> clean list of rules.
707
+ """
708
+ text_to_complete = event.symbol
609
709
  parts = event.line.split()
610
- ipyshell.user_ns.update(dict(rcon_event=event))
611
710
 
612
- arg_matches= []
613
- if len(parts) == 1: # showing commands
614
- arg_matches = [c for c in self.commands.keys()]
615
- ipyshell.user_ns.update({'rcon_matches':arg_matches})
616
- elif len(parts) == 2 and text != '': # completing commands
617
- arg_matches = [c for c in self.commands.keys() if c.startswith(text)]
618
- ipyshell.user_ns.update({'rcon_matches':arg_matches})
711
+ # Extract and normalize the command name
712
+ command = None
713
+ if len(parts) >= 2:
714
+ command = parts[1].replace('-', '_')
715
+ if ':' in command:
716
+ command = command.split(':')[-1]
717
+
718
+ arg_matches = []
719
+
720
+ # Case 1: Completing the base command
721
+ if len(parts) == 1 or (len(parts) == 2 and text_to_complete != ''):
722
+ arg_matches = [c for c in self.commands.keys() if c.startswith(text_to_complete)]
723
+
724
+ # Case 2: Showing/Completing sub-items (like gamerules)
725
+ elif len(parts) >= 2 and command in self.commands:
726
+ sub_map = self.commands[command]
727
+ sub_keys = [k for k in sub_map.keys() if k != ' ']
619
728
 
729
+ if len(parts) == 2 and text_to_complete == '':
730
+ arg_matches = sub_keys
731
+ elif len(parts) == 3 and text_to_complete != '':
732
+ arg_matches = [k for k in sub_keys if k.startswith(text_to_complete)]
733
+
734
+ ipyshell.user_ns.update({'rcon_matches': arg_matches})
620
735
  return arg_matches
621
736
 
622
737
  @line_magic
@@ -641,8 +756,14 @@ class MCShell(Magics):
641
756
  print('-' * 100)
642
757
  if _arg_list[0] == 'help':
643
758
  _responses = response.split('/')
644
- for _response in _responses:
645
- print('\t' + _response)
759
+ for _resp in _responses:
760
+ if _resp.strip():
761
+ # Keep namespaces, just fix hyphens
762
+ _parts = _resp.split()
763
+ _parts[0] = _parts[0].replace('-', '_')
764
+ print('\t' + ' '.join(_parts))
765
+ # for _response in _responses:
766
+ # print('\t' + _response)
646
767
  elif response.split()[0] == 'Unknown':
647
768
  print("[red]Error in usage:[/]")
648
769
  self.mc_help(line)
@@ -849,10 +970,13 @@ class MCShell(Magics):
849
970
  print("Currently running powers:", list(RUNNING_POWERS.keys()))
850
971
  return
851
972
 
852
- power_to_cancel = RUNNING_POWERS.get(execution_id)
853
- if power_to_cancel and execution_id in RUNNING_POWERS:
973
+ # Lookup the execution metadata in the global registry
974
+ power_metadata = RUNNING_POWERS.get(execution_id)
975
+
976
+ if power_metadata:
854
977
  print(f"Sending cancellation signal to power: {execution_id}")
855
- power_to_cancel['cancel_event'].set()
978
+ # Corrected Key: Simply 'cancel_event'
979
+ power_metadata['cancel_event'].set()
856
980
  else:
857
981
  print(f"Error: No running power found with ID: {execution_id}")
858
982
 
@@ -940,14 +1064,14 @@ class MCShell(Magics):
940
1064
  self.server_data = {
941
1065
  'host': Prompt.ask('Server Address:', default=self.server_data['host']),
942
1066
  'fj_port': int(Prompt.ask('Plugin Port:', default=str(self.server_data['fj_port']))),
943
- 'rcon_port':MC_RCON_PORT,
1067
+ 'rcon_port': int(Prompt.ask('Server Port:', default=str(self.server_data['rcon_port']))),
1068
+ 'app_port': int(Prompt.ask('Application Port:', default=str(self.server_data['app_port']))),
944
1069
  'password':None,
945
1070
  }
946
1071
 
947
1072
  login_to_server = Prompt.ask('Do you want to be a server op?',choices=['yes','no'],default='no')
948
1073
  if login_to_server.lower() == 'yes':
949
1074
  self.server_data.update({
950
- 'rcon_port': int(Prompt.ask('Server Port:', default=str(self.server_data['rcon_port']))),
951
1075
  'password': Prompt.ask('Server Password:', password=True)
952
1076
  })
953
1077
 
@@ -957,6 +1081,10 @@ class MCShell(Magics):
957
1081
  stop_app_server()
958
1082
  print(f"Starting application server for authorized Minecraft player: {minecraft_name}")
959
1083
  start_app_server(self.server_data,minecraft_name,self.shell,power_repo)
1084
+ print(f"Open a browser here to use the editor:")
1085
+ print(f"\thttp://{socket.gethostname()}.local:{self.server_data['app_port']}")
1086
+ print(f"Open a browser here to use the control:")
1087
+ print(f"\thttp://{socket.gethostname()}.local:{self.server_data['app_port']}/control")
960
1088
  return
961
1089
 
962
1090
  @line_magic
@@ -1029,7 +1157,6 @@ class MCShell(Magics):
1029
1157
  except requests.exceptions.RequestException as e:
1030
1158
  print(f"Error: Could not connect to the other player's application server. {e}")
1031
1159
 
1032
-
1033
1160
  @line_magic
1034
1161
  def mc_stdlib(self, line):
1035
1162
  """
@@ -1228,6 +1355,167 @@ class MCShell(Magics):
1228
1355
  except Exception as e:
1229
1356
  print(f"Sync failed: {e}")
1230
1357
 
1358
+ @line_magic
1359
+ def mc_library(self, line):
1360
+ """
1361
+ Management magic for your personal Minecraft Shell Power Library.
1362
+ Usage:
1363
+ %mc_library list - List all powers in your library.
1364
+ %mc_library rename-category <old> <new> - Rename a category in your library.
1365
+ %mc_library remove - Interactively remove powers from your library.
1366
+ %mc_library export <filepath.json> - Export selected powers to a JSON file.
1367
+ %mc_library import <filepath.json> - Import powers from a JSON file into your library.
1368
+ """
1369
+ import shlex # Ensure shlex is available
1370
+ from mcshell.mcrepo import PowerRepository, SQLiteRepository
1371
+
1372
+ try:
1373
+ args = shlex.split(line)
1374
+ except ValueError as e:
1375
+ print(f"Error parsing command line: {e}")
1376
+ return
1377
+
1378
+ if not args:
1379
+ print("Usage: %mc_library [list|rename-category|remove|export|import]")
1380
+ return
1381
+
1382
+ command = args[0]
1383
+ player = self.mc_name or self._get_mc_name()
1384
+ if not player:
1385
+ return
1386
+
1387
+ # Treat the repository purely as its interface type
1388
+ repo: PowerRepository = SQLiteRepository(player)
1389
+
1390
+ if command == "list":
1391
+ powers = repo.list_powers()
1392
+ if not powers:
1393
+ print(f"No powers found in your library ({player}).")
1394
+ return
1395
+ print(f"\nPowers in your library ({player}):")
1396
+ for i, p in enumerate(powers):
1397
+ print(f" [{i}] {p['name']} ({p.get('category', 'General')})")
1398
+
1399
+ elif command == "rename-category":
1400
+ if len(args) < 3:
1401
+ print("Usage: %mc_library rename-category <old_name> <new_name>")
1402
+ return
1403
+ old_name, new_name = args[1], args[2]
1404
+
1405
+ # Utilizing strictly the PowerRepository interface
1406
+ powers = repo.list_full_powers()
1407
+ count = 0
1408
+ for p in powers:
1409
+ cat = p.get('category', '')
1410
+ if cat == old_name:
1411
+ p['category'] = new_name
1412
+ repo.save_power(p)
1413
+ count += 1
1414
+ elif cat.startswith(f"{old_name}/"):
1415
+ p['category'] = new_name + cat[len(old_name):]
1416
+ repo.save_power(p)
1417
+ count += 1
1418
+
1419
+ print(f"Renamed {count} powers from '{old_name}' to '{new_name}'.")
1420
+ print("Refresh the editor to see changes.")
1421
+
1422
+ elif command == "remove":
1423
+ powers = repo.list_powers()
1424
+ if not powers:
1425
+ print("Your library is empty.")
1426
+ return
1427
+
1428
+ print("\nSelect powers to remove from your library:")
1429
+ for i, p in enumerate(powers):
1430
+ print(f" [{i}] {p['name']} ({p.get('category', 'General')})")
1431
+
1432
+ selection = Prompt.ask("Enter indices to remove (space separated)")
1433
+ try:
1434
+ indices_to_remove = [int(i) for i in selection.split()]
1435
+ except ValueError:
1436
+ print("Invalid selection.")
1437
+ return
1438
+
1439
+ removed_count = 0
1440
+ for idx in indices_to_remove:
1441
+ if 0 <= idx < len(powers):
1442
+ power_id = powers[idx]['power_id']
1443
+ if repo.delete_power(power_id):
1444
+ removed_count += 1
1445
+
1446
+ print(f"Successfully removed {removed_count} powers from your library.")
1447
+
1448
+ elif command == "export":
1449
+ if len(args) < 2:
1450
+ print("Usage: %mc_library export <filepath.json>")
1451
+ return
1452
+
1453
+ export_path = Path(args[1]).expanduser()
1454
+ powers = repo.list_full_powers()
1455
+ if not powers:
1456
+ print("Your library is empty. Nothing to export.")
1457
+ return
1458
+
1459
+ print(f"\nSelect powers to export to {export_path}:")
1460
+ for i, p in enumerate(powers):
1461
+ print(f" [{i}] {p['name']} ({p.get('category', 'General')})")
1462
+
1463
+ selection = Prompt.ask("Enter indices to export (space separated, or 'all')")
1464
+
1465
+ if selection.lower() == 'all':
1466
+ powers_to_export = powers
1467
+ else:
1468
+ try:
1469
+ selected_indices = [int(i) for i in selection.split()]
1470
+ powers_to_export = [powers[i] for i in selected_indices if 0 <= i < len(powers)]
1471
+ except (ValueError, IndexError):
1472
+ print("Invalid selection.")
1473
+ return
1474
+
1475
+ if not powers_to_export:
1476
+ print("No valid powers selected for export.")
1477
+ return
1478
+
1479
+ export_data = {"powers": powers_to_export}
1480
+ export_path.parent.mkdir(parents=True, exist_ok=True)
1481
+ with export_path.open('w') as f:
1482
+ json.dump(export_data, f, indent=4)
1483
+
1484
+ print(f"Successfully exported {len(powers_to_export)} powers to {export_path}.")
1485
+
1486
+ elif command == "import":
1487
+ if len(args) < 2:
1488
+ print("Usage: %mc_library import <filepath.json>")
1489
+ return
1490
+
1491
+ import_path = Path(args[1]).expanduser()
1492
+ if not import_path.exists():
1493
+ print(f"Error: File not found at {import_path}")
1494
+ return
1495
+
1496
+ try:
1497
+ with import_path.open('r') as f:
1498
+ data = json.load(f)
1499
+
1500
+ # Handle standard {"powers": [...]} structure or legacy flat list/dict structures
1501
+ if isinstance(data, dict) and "powers" in data:
1502
+ powers_to_import = data["powers"]
1503
+ else:
1504
+ powers_to_import = data if isinstance(data, list) else data.values()
1505
+
1506
+ count = 0
1507
+ for p_data in powers_to_import:
1508
+ repo.save_power(p_data)
1509
+ count += 1
1510
+
1511
+ print(f"Successfully imported {count} powers into your library from {import_path}.")
1512
+ except Exception as e:
1513
+ print(f"Error importing powers: {e}")
1514
+
1515
+ else:
1516
+ print(f"Unknown command: {command}")
1517
+ print("Usage: %mc_library [list|rename-category|remove|export|import]")
1518
+
1231
1519
  def sync_datapack_library():
1232
1520
  """
1233
1521
  Synchronizes the internal datapack library to the user's worlds directory.
@@ -1,9 +1,6 @@
1
1
  import eventlet
2
- from rcon.source import Client
3
- from aiomcrcon import Client as AioClient
4
-
5
- from rcon.errorhandler import WrongPassword
6
- from aiomcrcon.errors import IncorrectPasswordError
2
+ from mctools import RCONClient, AsyncRCONClient
3
+ from mctools.errors import RCONAuthenticationError
7
4
 
8
5
  import os
9
6
  import re
@@ -52,11 +49,12 @@ except ImportError: # Graceful fallback if IceCream isn't installed.
52
49
  # the default version when using %pp_create_world
53
50
  MC_VERSION = '1.21.11' # this must match the client version
54
51
 
55
- # default server data
52
+ # default server data; avoid common ports
56
53
  MC_SERVER_HOST = 'localhost'
57
- MC_RCON_PORT = 25575
58
- MC_SERVER_PORT = 25565
59
- FJ_PLUGIN_PORT = 4711
54
+ MC_RCON_PORT = 25576
55
+ MC_SERVER_PORT = 25566
56
+ FJ_PLUGIN_PORT = 4712
57
+ MC_APP_PORT = 5001
60
58
 
61
59
 
62
60
  MC_SERVER_DATA = {
@@ -64,6 +62,7 @@ MC_SERVER_DATA = {
64
62
  'port':MC_SERVER_PORT,
65
63
  'rcon_port':MC_RCON_PORT,
66
64
  'fj_port': FJ_PLUGIN_PORT,
65
+ 'app_port': MC_APP_PORT,
67
66
  'password': None,
68
67
  }
69
68
 
@@ -82,11 +81,14 @@ MC_COLOURABLE_MATERIALS_DATA_PATH = MC_DATA_DIR.joinpath('materials/colourables.
82
81
  MC_PICKER_MATERIALS_DATA_PATH = MC_DATA_DIR.joinpath('materials/pickers.json')
83
82
  MC_SINGLE_MATERIALS_DATA_PATH = MC_DATA_DIR.joinpath('materials/singles.json')
84
83
 
84
+ MC_ITEM_ID_MAP_PATH = MC_DATA_DIR.joinpath('materials/item_id_map.pkl')
85
+
85
86
  # here is the source of truth for Entity IDs like in pyncraft.entity
86
87
  MC_ENTITY_TYPE_URL = yarl.URL("https://raw.githubusercontent.com/PaperMC/Paper/refs/heads/main/paper-api/src/main/java/org/bukkit/entity/EntityType.java")
87
88
  MC_ENTITY_ID_MAP_PATH = MC_DATA_DIR.joinpath('entities/entity_id_map.pkl')
88
89
  MC_ENTITY_PICKERS_PATH = MC_DATA_DIR.joinpath('entities/pickers.json')
89
90
 
91
+
90
92
  MC_APP_DIR = MC_DATA_DIR.joinpath('app')
91
93
 
92
94
  MC_APP_STATIC_DIR = MC_DATA_DIR.joinpath('static')
@@ -1,4 +1,4 @@
1
- <!DOCTYPE html><html lang=en><script type=importmap>{"imports":{"2N3MJ":"/toolbox.48fd1f79.xml"}}</script><script type=module src=/mced.a4de160c.js></script><link rel=stylesheet href=/mced.efd4d8e7.css><meta charset=utf-8><title>MC-ED Editor</title><link rel=stylesheet href=/mced.55f94dd4.css><body x-data="{ isLibraryCollapsed: true, isCodeCollapsed: true, keyboardVisible: false }">
1
+ <!DOCTYPE html><html lang=en><script type=importmap>{"imports":{"2N3MJ":"/toolbox.193e3fba.xml"}}</script><script type=module src=/mced.a4de160c.js></script><link rel=stylesheet href=/mced.efd4d8e7.css><meta charset=utf-8><title>MC-ED Editor</title><link rel=stylesheet href=/mced.3f8a9cca.css><body x-data="{ isLibraryCollapsed: true, isCodeCollapsed: true, keyboardVisible: false }">
2
2
 
3
3
  <div class="code-collapsed editor-layout library-collapsed" :class="{ 'library-collapsed': isLibraryCollapsed, 'code-collapsed': isCodeCollapsed }">
4
4
  <aside id=power-library-panel>
@@ -128,7 +128,7 @@
128
128
 
129
129
  </div>
130
130
 
131
- <script type=module src=/mced.484d99b8.js></script>
131
+ <script type=module src=/mced.3d4a5c3d.js></script>
132
132
  <div class=simple-keyboard x-show=keyboardVisible style=z-index:20000;background:#fff;width:100%;position:fixed;bottom:0;left:0>
133
133
  </div>
134
134