Voici une version, inspirée par le pexpect
un ci-dessus.
Pour l'exécuter, il faut utiliser Python 3 et avoir click
installé (peut-être dans un environnement virtuel). Ensuite, trouvez de l'aide dans la ligne de commande :
$ 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.
En partant d'un point, il téléporte le joueur en spirale vers l'extérieur, étape par étape, jusqu'à ce qu'une certaine largeur soit atteinte.
Le code ci-dessous suppose que votre monde s'exécute dans un environnement de type image docker . Modifier le run_mc_command
pour s'adapter à votre hébergement.
Il est lent : générer un monde de 1000x1000 est (1000/16)^2 = 3906 téléportations à un minimum d'une demi-seconde chacune.
Voici le 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()