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.
- {mc_shell-0.7.0 → mc_shell-0.7.2}/PKG-INFO +2 -3
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/__init__.py +360 -72
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/constants.py +11 -9
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/index.html +2 -2
- mc_shell-0.7.0/mcshell/data/app/mced.484d99b8.js → mc_shell-0.7.2/mcshell/data/app/mced.3d4a5c3d.js +127 -86
- 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
- mc_shell-0.7.2/mcshell/data/app/mced.3f8a9cca.css +2 -0
- mc_shell-0.7.2/mcshell/data/app/mced.3f8a9cca.css.map +1 -0
- mc_shell-0.7.2/mcshell/data/app/toolbox.193e3fba.xml +503 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/materials/colourables.json +154 -154
- mc_shell-0.7.2/mcshell/data/materials/entity_overrides.json +4 -0
- mc_shell-0.7.2/mcshell/data/materials/item_id_map.pkl +0 -0
- mc_shell-0.7.2/mcshell/data/materials/materials.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/materials/pickers.json +184 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/materials/singles.json +2 -171
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/powers/stdlib.json +2669 -1
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/toolbox_template.xml +1 -1
- mc_shell-0.7.2/mcshell/digitalgeometryactions.py +60 -0
- mc_shell-0.7.2/mcshell/digitalsetactions.py +243 -0
- mc_shell-0.7.0/mcshell/mceventactions.py → mc_shell-0.7.2/mcshell/eventactions.py +0 -7
- mc_shell-0.7.2/mcshell/mcactions.py +117 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcactions_base.py +41 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcblockly.py +140 -123
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcclient.py +48 -27
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcplayer.py +27 -16
- mc_shell-0.7.2/mcshell/mcscraper.py +300 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcserver.py +2 -2
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcturtle.py +63 -18
- mc_shell-0.7.2/mcshell/playeractions.py +75 -0
- mc_shell-0.7.2/mcshell/pyncraftcactions.py +148 -0
- mc_shell-0.7.2/mcshell/qturtleactions.py +122 -0
- mc_shell-0.7.2/mcshell/registry_builder.py +619 -0
- mc_shell-0.7.2/mcshell/serveractions.py +249 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/pyproject.toml +2 -3
- mc_shell-0.7.0/mcshell/data/app/mced.55f94dd4.css +0 -2
- mc_shell-0.7.0/mcshell/data/app/mced.55f94dd4.css.map +0 -1
- mc_shell-0.7.0/mcshell/data/app/toolbox.48fd1f79.xml +0 -758
- mc_shell-0.7.0/mcshell/data/materials/entity_overrides.json +0 -4
- mc_shell-0.7.0/mcshell/data/materials/materials.pkl +0 -0
- mc_shell-0.7.0/mcshell/mcactions.py +0 -454
- mc_shell-0.7.0/mcshell/mcscraper.py +0 -238
- mc_shell-0.7.0/mcshell/pyncactions.py +0 -262
- mc_shell-0.7.0/mcshell/serveractions.py +0 -204
- {mc_shell-0.7.0 → mc_shell-0.7.2}/LICENSE +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/README.md +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/Matrix3.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/Vec3.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/blueprints/control_api.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/blueprints/ipython_api.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/blueprints/powers_api.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/FruitJuice-0.3.0.jar +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/FruitJuice-0.4.0.jar +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/FruitJuice-0.4.1.jar +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/control.a8439284.css +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/control.a8439284.css.map +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/control.b03e9afc.js +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/control.b03e9afc.js.map +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/control.html +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/mced.a4de160c.js +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/mced.a4de160c.js.map +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/mced.efd4d8e7.css +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/app/mced.efd4d8e7.css.map +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/control_layout.json +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/flat_world/data/minecraft/dimension/overworld.json +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/flat_world/data/minecraft/worldgen/biome/the_void.json +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/flat_world/pack.mcmeta +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/void_world/data/minecraft/dimension/overworld.json +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/void_world/data/minecraft/functions/init.mcfunction +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/void_world/data/minecraft/tags/functions/load.json +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/void_world/data/minecraft/worldgen/biome/the_void.json +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/datapacks/void_world/pack.mcmeta +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/doc/command_docs.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/entities/entity_id_map.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/entities/generate_entity_blocks.mjs +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/entities/pickers.json +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/materials/generate_material_blocks.mjs +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/materials/mcblocks.csv +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/paper-global-template.yaml +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/%3F.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/Commands.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/EntityType.java.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/Material.html.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/ability.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/advancement.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/alwaysday.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/attribute.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/ban-ip.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/ban.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/banlist.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/bossbar.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/camera.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/camerashake.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/changesetting.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/clear.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/clearspawnpoint.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/clone.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/connect.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/damage.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/data.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/datapack.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/daylock.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/debug.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/dedicatedwsserver.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/defaultgamemode.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/deop.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/dialogue.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/difficulty.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/effect.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/enchant.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/event.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/execute.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/experience.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/fill.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/fillbiome.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/fog.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/forceload.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/function.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/gamemode.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/gamerule.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/gametest.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/give.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/help.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/immutableworld.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/item.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/jfr.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/kick.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/kill.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/list.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/locate.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/loot.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/me.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/mobevent.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/msg.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/music.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/op.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/ops.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/pardon-ip.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/pardon.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/particle.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/perf.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/permission.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/place_(Java_Edition).pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/playanimation.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/playsound.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/publish.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/random.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/recipe.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/reload.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/remove.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/replaceitem.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/return.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/ride.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/save-all.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/save-off.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/save-on.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/save.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/say.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/schedule.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/scoreboard.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/script.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/scriptevent.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/seed.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/setblock.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/setidletimeout.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/setmaxplayers.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/setworldspawn.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/spawnpoint.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/spectate.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/spreadplayers.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/stop.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/stopsound.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/structure.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/summon.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tag.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/team.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/teammsg.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/teleport.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tell.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tellraw.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/testfor.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/testforblock.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/testforblocks.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tickingarea.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/time.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/title.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/titleraw.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tm.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/toggledownfall.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/tp.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/transferserver.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/trigger.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/volumearea.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/w.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/wb.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/weather.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/whitelist.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/worldborder.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/worldbuilder.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/wsserver.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/data/webpage-cache/xp.pkl +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcexperience_base.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mclsystem.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcrepo.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcshell.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcvoxel.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/mcvoxel_original.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/ppdownloader.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/ppmanager.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/__init__.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/block.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/connection.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/entity.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/event.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/logger.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/minecraft.py +0 -0
- {mc_shell-0.7.0 → mc_shell-0.7.2}/mcshell/vendored/pyncraft/util.py +0 -0
- {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.
|
|
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
|
|
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
|
-
"
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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:'
|
|
583
|
-
|
|
584
|
-
|
|
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
|
|
589
|
-
print(
|
|
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
|
-
|
|
594
|
-
|
|
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
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
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
|
-
|
|
608
|
-
|
|
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
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
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
|
|
645
|
-
|
|
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
|
-
|
|
853
|
-
|
|
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
|
-
|
|
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':
|
|
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
|
|
3
|
-
from
|
|
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 =
|
|
58
|
-
MC_SERVER_PORT =
|
|
59
|
-
FJ_PLUGIN_PORT =
|
|
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.
|
|
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.
|
|
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
|
|