Source code for miney.player

from typing import Union
import miney

# todo: set modes creative/survival -> Not possible without installed minetest mods

[docs]class Player: """ A player of the minetest server. """ def __init__(self, minetest: miney.Minetest, name): """ Initialize the player object. :param minetest: Parent minetest object :param name: Player name """ = minetest = name # get user data: password hash, last login, privileges data ="return minetest.get_auth_handler().get_auth('{}')".format( if data and all(k in data for k in ("password", "last_login", "privileges")): # if we have all keys self.password = data["password"] self.last_login = data["last_login"] self.privileges = data["privileges"] else: raise miney.PlayerInvalid("There is no player with that name") self.inventory: miney.Inventory = miney.Inventory(minetest, self) """Manipulate player's inventory. :Example to add 99 dirt to player "IloveDirt"'s inventory: >>> import miney >>> mt = miney.Minetest() >>> mt.player.IloveDirt.inventory.add(mt.node.type.default.dirt, 99) :Example to remove 99 dirt from player "IhateDirt"'s inventory: >>> import miney >>> mt = miney.Minetest() >>> mt.player.IhateDirt.inventory.remove(mt.node.type.default.dirt, 99) """ def __repr__(self): return '<minetest player "{}">'.format( @property def is_online(self) -> bool: """ Returns the online status of this player. :return: True or False """ # TODO: Better check without provoke a lua error try: if == "return minetest.get_player_by_name('{}'):get_player_name()".format( return True except miney.LuaError: return False @property def position(self) -> dict: """ Get the players current position. :return: A dict with x,y,z keys: {"x": 0, "y":1, "z":2} """ try: return"return minetest.get_player_by_name('{}'):get_pos()".format( except miney.LuaError: raise miney.PlayerOffline("The player has no position, he could be offline") @position.setter def position(self, values: dict): """ Set player position :param values: :return: """ if all(k in values for k in ("x", "y", "z")): # if we have all keys "return minetest.get_player_by_name('{}'):set_pos({{x = {}, y = {}, z = {}}})".format(, values["x"], values["y"], values["z"], ) ) else: raise miney.NoValidPosition( "A valid position need x,y,z values in an dict ({\"x\": 12, \"y\": 70, \"z\": 12}).") @property def speed(self) -> int: """ Get or set the players speed. Default is 1. :return: Float """ return "return minetest.get_player_by_name('{}'):get_physics_override()".format(["speed"] @speed.setter def speed(self, value: int): "return minetest.get_player_by_name('{}'):set_physics_override({{speed = {}}})".format(, value)) @property def jump(self): """ Get or set the players jump height. Default is 1. :return: Float """ return "return minetest.get_player_by_name('{}'):get_physics_override()".format(["jump"] @jump.setter def jump(self, value): "return minetest.get_player_by_name('{}'):set_physics_override({{jump = {}}})".format(, value)) @property def gravity(self): """ Get or set the players gravity. Default is 1. :return: Float """ return "return minetest.get_player_by_name('{}'):get_physics_override()".format(["gravity"] @gravity.setter def gravity(self, value): "return minetest.get_player_by_name('{}'):set_physics_override({{gravity = {}}})".format(, value)) @property def look(self) -> dict: """ Get and set look in radians. Horizontal angle is counter-clockwise from the +z direction. Vertical angle ranges between -pi/2 (~-1.563) and pi/2 (~1.563), which are straight up and down respectively. :return: A dict like {'v': 0.34, 'h': 2.50} where h is horizontal and v = vertical """ return f"return {{" f"h=minetest.get_player_by_name('{}'):get_look_horizontal(), " f"v=minetest.get_player_by_name('{}'):get_look_vertical()" f"}}" ) @look.setter def look(self, value: dict): if type(value) is dict: if "v" in value and "h" in value: if type(value["v"]) in [int, float] and type(value["h"]) in [int, float]: f""" local player = minetest.get_player_by_name('{}') player:set_look_horizontal({value["h"]}) player:set_look_vertical({value["v"]}) return true """ ) else: raise TypeError("values for v or h aren't float or int") else: raise TypeError("There isn't the required v or h key in the dict") else: raise TypeError("The value isn't a dict, as required. Use a dict in the form: {\"h\": 1.1, \"v\": 1.1}") @property def look_vertical(self): """ Get and set pitch in radians. Angle ranges between -pi/2 (~-1.563) and pi/2 (~1.563), which are straight up and down respectively. :return: Pitch in radians """ return"return minetest.get_player_by_name('{}'):get_look_vertical()".format( @look_vertical.setter def look_vertical(self, value):"return minetest.get_player_by_name('{}'):set_look_vertical({})".format(, value)) @property def look_horizontal(self): """ Get and set yaw in radians. Angle is counter-clockwise from the +z direction. :return: Pitch in radians """ return"return minetest.get_player_by_name('{}'):get_look_horizontal()".format( @look_horizontal.setter def look_horizontal(self, value):"return minetest.get_player_by_name('{}'):set_look_horizontal({})".format(, value)) @property def hp(self): """ Get and set the number of hitpoints (2 * number of hearts) between 0 and 20. By setting his hitpoint to zero you instantly kill this player. :return: """ return"return minetest.get_player_by_name('{}'):get_hp()") @hp.setter def hp(self, value: int): if type(value) is int and value in range(0, 21): f"return minetest.get_player_by_name('{}'):set_hp({value}, {{type=\"set_hp\"}})") else: raise ValueError("HP has to be between 0 and 20.") @property def breath(self): return"return minetest.get_player_by_name('{}'):get_breath()") @breath.setter def breath(self, value: int): if type(value) is int and value in range(0, 21): f"return minetest.get_player_by_name('{}'):set_breath({value}, {{type=\"set_hp\"}})") else: raise ValueError("HP has to be between 0 and 20.") @property def fly(self) -> bool: """ Get and set the privilege to fly to this player. Press K to enable and disable fly mode. As a shortcut you can set fly to a number instead if `True` to also changes the players speed to this number. .. Example: >>> = True # the can player fly >>> = 5 # the can player fly 5 times faster :return: """ return f""" local privs = minetest.get_player_privs(\"{}\") if privs["fly"] then return true else return false end """ ) @fly.setter def fly(self, value: Union[bool, int]): if value: state = "true" if type(value) is int: if value > 0: self.speed = value else: state = "false" f""" local privs = minetest.get_player_privs(\"{}\") privs["fly"] = {state} minetest.set_player_privs(\"{}\", privs) """ ) @property def creative(self) -> bool: return f""" local privs = minetest.get_player_privs(\"{}\") if privs["creative"] then return true else return false end """ ) @creative.setter def creative(self, value: bool): if type(value) is not bool: raise ValueError("creative needs to be true or false") if value is True: state = "true" else: state = "false" luastring = f""" local privs = minetest.get_player_privs(\"{}\") privs["creative"] = {state} minetest.set_player_privs(\"{}\", privs) """ luastring )
class PlayerIterable: """Player, implemented as iterable for easy autocomplete in the interactive shell""" def __init__(self, minetest: miney.Minetest, online_players: list = None): if online_players: self.__online_players = online_players self.__mt = minetest # update list for player in online_players: self.__setattr__(player, miney.Player(minetest, player)) def __iter__(self): player_object = [] for player in self.__online_players: player_object.append(miney.Player(self.__mt, player)) return iter(player_object) def __getitem__(self, item_key) -> Player: if item_key in self.__online_players: return self.__getattribute__(item_key) else: if type(item_key) == int: return self.__getattribute__(self.__online_players[item_key]) raise IndexError("unknown player") def __len__(self): return len(self.__online_players)