Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 62 additions & 5 deletions demo/test.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
"""
this file aims to call nearly all functions at least once
there are not many assertions. it's more a "do we pass all signatures correctly" test
"""

# TODO: von chat auslesen is untested

import time

import st_minecraft.de as st_minecraft
import st_minecraft.de.boss_leiste as boss_bar
from st_minecraft.en import Dimension

st_minecraft.verbinden()

""" test title"""

st_minecraft.zeige_titel("Hallo Welt!")

"""test player getters"""

spieler = st_minecraft.hole_spieler()

spieler_durch_name = st_minecraft.hole_spieler_durch_name(spieler.name)
Expand All @@ -17,14 +29,14 @@

assert spieler == spieler_durch_index

cmd = f"op {spieler.name}"
st_minecraft.sende_befehl(cmd)
print(cmd)
""" test player positioning"""


st_minecraft.spieler_position_setzen(spieler, spieler.x, spieler.y - 20, spieler.z, dimension=Dimension.Nether)
st_minecraft.spieler_position_setzen(spieler, spieler.x, spieler.y + 20, spieler.z, dimension=Dimension.World)

""" test player attributes"""

st_minecraft.spieler_leben_setzen(spieler, 20)

st_minecraft.spieler_max_leben_setzten(spieler, 40)
Expand All @@ -35,15 +47,28 @@

st_minecraft.spieler_xp_fortschritt_setzen(spieler, 0.5)

st_minecraft.spieler_geschwindigkeit_setzen(spieler, st_minecraft.RichtungSammlung.Hoch, 10)

"""
entity tests
"""

entity = st_minecraft.erzeuge_entity(spieler.x, spieler.y, spieler.z, st_minecraft.EntitySammlung.Kuh)
entity = st_minecraft.entity_name_setzen(entity, "Test")
entity = st_minecraft.entity_position_setzen(entity, entity.x, entity.y, entity.z)
print(entity.name)
entity = st_minecraft.entity_ai_setzen(entity, False)
entity = st_minecraft.entity_leben_setzen(entity, 1)

st_minecraft.gebe_item(spieler, st_minecraft.MaterialSammlung.Holzspitzhacke, 1, name="Test")
print(st_minecraft.hole_inventar(spieler))
e2 = st_minecraft.hole_entity(entity)

assert entity.id == e2.id


"""
block tests
"""

for i in range(1, 10, 2):
p = st_minecraft.hole_spieler()
offset = i * 0.01
Expand All @@ -52,6 +77,9 @@
time.sleep(0.2)
print(p.x)

"""
float test
"""

b = st_minecraft.hole_block(0, 100.34, 0)
if b.typ == st_minecraft.MaterialSammlung.Goldblock:
Expand All @@ -69,4 +97,33 @@
else:
raise AssertionError("Set block doesnt match")

"""
command test
"""

st_minecraft.sende_befehl("time set day")

"""
chat test
"""
st_minecraft.sende_an_chat("Test!")

"""inventory tests"""

st_minecraft.gebe_item(spieler, st_minecraft.MaterialSammlung.Holzspitzhacke, 1, name="Test")
inv = st_minecraft.hole_inventar(spieler)

print(inv)

"""
boss bar tests
"""

bb = boss_bar.erzeuge_leiste("test", "test")

boss_bar.setze_farbe(bb, boss_bar.BossLeisteFarben.PINK)

boss_bar.loesche_leiste(bb)


print(f"SUCCESS")
29 changes: 28 additions & 1 deletion st_minecraft/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
connection: Optional[socket.socket] = None

ARG_SEPARATOR = "𝇉"
_SUCCESS_MESSAGE = f"{ARG_SEPARATOR}success{ARG_SEPARATOR}"
"""used to signal that a command was successful (when no other data response is expected)"""

DEFAULT_PORT = 25595

Expand Down Expand Up @@ -146,6 +148,28 @@ def _receive(timeout: float = 2.0) -> bytes | None:
return data


def _receive_raise_if_command_error() -> None:
"""
all commands that expect no value in return, instead receive a success/failure message
this is "success" for success and else a failure message.

this function is meant to be called after a command is sent that doesn't expect a return value

Returns:
nothing on success

Raises:
ConnectionError or ValueError on failure
"""
data = _receive()
if data is None:
raise ConnectionError(f"Did not receive any data in time, as response to command")

response = _bytes_to_text(data)
if response != _SUCCESS_MESSAGE:
raise ValueError(f"Server received command but responded with error: {response}")


def _to_int(*args) -> tuple[int, ...]:
"""args to int"""
return tuple(map(int, args))
Expand Down Expand Up @@ -173,19 +197,22 @@ def _bytes_to_text(b: bytes) -> str:
return b.decode("utf-8").strip()


def _send_command(command: str) -> None:
def _send_command(command: str, validate: bool = False) -> None:
"""
Sends a command over the global connection.

Args:
command (str): The command to send.
validate: if True _receive_raise_if_command_error() is called, a function to validate a success response
"""
# needed internally
if connection is None:
raise RuntimeError("No connection to server. Please connect first.")

command = f"{command}\n"
connection.sendall(command.encode("utf-8"))
if validate:
_receive_raise_if_command_error()


E = TypeVar("E", bound=Enum)
Expand Down
8 changes: 5 additions & 3 deletions st_minecraft/en/boss_bar.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from st_minecraft.core.core import _build_command
from st_minecraft.core.core import _send_command

# TODO: there is a GetBossBar command in the backend that seems to be unused in the frontend


class BossBarStyle(Enum):
"""Ways in which the style of a boss bar can be displayed"""
Expand Down Expand Up @@ -58,7 +60,7 @@ def __repr__(self):
def _send_boss_bar_command(sub_command: str):
# needed internally
command = f"editBossBar{ARG_SEPARATOR}{sub_command}"
_send_command(command)
_send_command(command, validate=True)


def create_bar(name: str, display_text: str) -> BossBar:
Expand All @@ -72,7 +74,7 @@ def create_bar(name: str, display_text: str) -> BossBar:
A BossBar object with which you can further configure the bar
"""
command = _build_command("spawnBossBar", name, display_text)
_send_command(command)
_send_command(command, validate=True)

# some of the values are set when creating.
return BossBar(
Expand Down Expand Up @@ -126,4 +128,4 @@ def delete_bar(boss_bar: BossBar):

def _delete_bar_str(boss_bar_name: str):
command = _build_command("deleteBossBar", boss_bar_name)
_send_command(command)
_send_command(command, validate=True)
32 changes: 17 additions & 15 deletions st_minecraft/en/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def set_block(
def get_block(x: float, y: float, z: float, dimension: Dimension = Dimension.World) -> Material:
"""
Query what type of block is at the coordinate
You get a block object back that contains the type under .typ
You get a block object back that contains the type under .type
Note: An "empty" block is treated as an air block.

Args:
Expand Down Expand Up @@ -171,7 +171,7 @@ def send_to_chat(message: str):
message: The message you want to send
"""
command = _build_command("postChat", message)
_send_command(command)
_send_command(command, validate=True)


def get_chat() -> list[Message]:
Expand Down Expand Up @@ -236,7 +236,7 @@ def show_title(
seconds_to_ticks(display_time),
seconds_to_ticks(fade_out_time),
)
_send_command(command)
_send_command(command, validate=True)


def send_command(command: str):
Expand All @@ -249,7 +249,7 @@ def send_command(command: str):
if command.startswith("/"):
print("Warning: You entered a '/' at the beginning of the command. This is probably not necessary!")
command = _build_command("chatCommand", command)
_send_command(command)
_send_command(command, validate=True)


def spawn_entity(
Expand All @@ -272,7 +272,7 @@ def spawn_entity(
"""
command = _build_command("spawnEntity", x, y, z, dimension.value, entity.value)
print(command)
_send_command(command)
_send_command(command, validate=True)
data = _receive()
entity = Entity.from_api_format(_bytes_to_text(data))
return entity
Expand Down Expand Up @@ -318,7 +318,7 @@ def give_item(
args.append("unbreakable")

command = _build_command(*args)
_send_command(command)
_send_command(command, validate=True)

return get_inventory(player)

Expand Down Expand Up @@ -408,7 +408,7 @@ def set_player_velocity(player: Player, direction: DirectionCollection, value: f

"""
command = _build_command("setPlayerVelocity", direction.value, player.id, value)
_send_command(command)
_send_command(command, validate=True)
return get_player(index=player.id)


Expand Down Expand Up @@ -484,6 +484,12 @@ def _set_player_property(type: str, player: Player, value: float):
_send_command(command)


def _edit_entity_command(entity: Entity, *args) -> None:
"""internal edit entity function"""
command = _build_command("editEntity", entity.id, *args)
_send_command(command, validate=True)


def set_entity_name(entity: Entity, name: str) -> Entity:
"""
Set the name of an entity
Expand All @@ -493,8 +499,7 @@ def set_entity_name(entity: Entity, name: str) -> Entity:
Returns:
An updated version of the entity (state after the change)
"""
command = _build_command("editEntity", entity.id, f"name:{name}")
_send_command(command)
_edit_entity_command(entity, f"name:{name}")
return get_entity(entity)


Expand All @@ -511,8 +516,7 @@ def set_entity_position(entity: Entity, x: float, y: float, z: float, dimension:
Returns:
An updated version of the entity (state after the change)
"""
command = _build_command("editEntity", entity.id, f"position:{x};{y};{z};{dimension.value}")
_send_command(command)
_edit_entity_command(entity, f"position:{x};{y};{z};{dimension.value}")
return get_entity(entity)


Expand All @@ -527,8 +531,7 @@ def set_entity_ai(entity: Entity, status: bool) -> Entity:
Returns:
An updated version of the entity (state after the change)
"""
command = _build_command("editEntity", entity.id, f"ai:{status}")
_send_command(command)
_edit_entity_command(entity, f"ai:{status}")
return get_entity(entity)


Expand All @@ -540,8 +543,7 @@ def set_entity_health(entity: Entity, health: float) -> Entity:
entity: The entity to be edited, not EntitySammlung!
health: How many health points the entity should have (0=dead).
"""
command = _build_command("editEntity", entity.id, f"health:{health}")
_send_command(command)
_edit_entity_command(entity, f"health:{health}")
return get_entity(entity)


Expand Down