Here is a version, inspired by the pexpect
one above.
To run, use Python 3 and have click
installed (maybe in a virtual environment). Then, find help in the command line:
$ python explore.py --help
Usage: explore.py [OPTIONS]
Travel your minecraft world
Options:
-p, --player TEXT Set this a a logged in minecraft player name
-s, --start TEXT Starting point x:z
-r, --radius INTEGER Width of the world you want generated
--help Show this message and exit.
Starting from a point, it will teleport a player in an outward spiral by step until a certain width is attained.
The code below presumes your world is running in a docker image. Edit the run_mc_command
function to fit your hosting.
It is slow: Generating a 1000x1000 world is (1000/16)^2 = 3906 teleports at minimum half a second each.
Here is the code:
#!/usr/bin/python
from subprocess import run
from itertools import cycle, count
import click
@click.command()
@click.option("-p", "--player",
help="Set this a a logged in minecraft player name")
@click.option("-s", "--start",
help="Starting point x:z",
default="0:0")
@click.option("-r", "--radius",
help="Width of the world you want generated",
default=5000)
def main(player: str, start: str, radius):
"""Travel your minecraft world"""
start = start.split(":", 2)
parsed_start = float(start[0]), float(start[1])
click.echo("Exploring world")
click.echo(f" Puppeteering {player!s}")
click.echo(f" Starting from {parsed_start!s}")
click.echo(f" Until reached {radius!s} meters radius (square, of course)")
explore(player, parsed_start, float(radius))
def explore(player: str, start: tuple, width: float, step: float = 16) -> None:
"""
Travel you minecaft world
Args:
player: A logged in player will be teleported. This is its playername.
start: Starting coordinate (x, z).
width: Width of the square you want explored.
step: Length of jumps. Defaults to 16 minecraft blocks.
"""
run_mc_command(f"gamemode creative {player!s}")
for position in walk_spiral(start, step):
run_mc_command(f"tp {player!s} {position[0]!s} 255 {position[1]!s}")
distance = position[0] - start[0], position[1] - start[1]
if distance[0] > width:
break
def run_mc_command(command: str) -> None:
"""
Run a Minecraft console command..
Here you can customize base on where you world is hosted. This
implementation use the itzg/minecraft-server docker image.
Args:
command: A Minecraft command, such as "say hello"
"""
run(
[
"docker", "exec", "mc", "rcon-cli",
command
]
)
def walk_spiral(start: tuple, step: float = 16) -> tuple:
"""
Generate positions to teleport to.
This is an infinite generator.
Args:
start: Starting position
step: Length of jumps.
Yields:
Position to teleport to in a spiral.
"""
current_movement_x, current_movement_z = start
movements = spiral_movements()
while True:
yield current_movement_x, current_movement_z
next_x_movement, next_y_movement = next(movements)
current_movement_x += next_x_movement * step
current_movement_z += next_y_movement * step
def spiral_movements():
def _spiral_distances():
for steps in count(1):
for _ in (0, 1):
yield steps
def _clockwise_directions():
left = (-1, 0)
right = (1, 0)
up = (0, -1)
down = (0, 1)
return cycle((right, down, left, up))
for distance, direction in zip(_spiral_distances(), _clockwise_directions()):
for _ in range(distance):
yield direction
if __name__ == "__main__":
main()