Example #1
0
    def player(cls, name, player_list=None):
        """Get a Player instance from the name, client ID,
        or Steam ID. Assumes [0, 64) to be a client ID
        and [64, inf) to be a Steam ID.

        """
        # In case 'name' isn't a string.
        if isinstance(name, minqlx.Player):
            return name
        elif isinstance(name, int) and 0 <= name < 64:
            return minqlx.Player(name)

        if not player_list:
            players = cls.players()
        else:
            players = player_list

        if isinstance(name, int) and name >= 64:
            for p in players:
                if p.steam_id == name:
                    return p
        else:
            cid = cls.client_id(name, players)
            if cid:
                for p in players:
                    if p.id == cid:
                        return p

        return None
Example #2
0
def handle_server_command(client_id: int, cmd: str):
    # noinspection PyBroadException
    try:
        # Dispatch the "server_command" event before further processing.
        try:
            player = minqlx.Player(client_id) if client_id >= 0 else None
        except minqlx.NonexistentPlayerError:
            return True

        retval = minqlx.EVENT_DISPATCHERS["server_command"].dispatch(
            player, cmd)
        if retval is False:
            return False
        if isinstance(retval, str):
            cmd = retval

        res = _re_vote_ended.match(cmd)
        if res:
            if res.group("result") == "passed":
                minqlx.EVENT_DISPATCHERS["vote_ended"].dispatch(True)
            else:
                minqlx.EVENT_DISPATCHERS["vote_ended"].dispatch(False)

        return cmd
    except:  # pylint: disable=bare-except
        minqlx.log_exception()
        return True
Example #3
0
def handle_client_command(client_id, cmd):
    """Client commands are commands such as "say", "say_team", "scores",
    "disconnect" and so on. This function parses those and passes it
    on to the event dispatcher.

    :param client_id: The client identifier.
    :type client_id: int
    :param cmd: The command being ran by the client.
    :type cmd: str

    """
    try:
        # Dispatch the "client_command" event before further processing.
        player = minqlx.Player(client_id)
        if minqlx.EVENT_DISPATCHERS["client_command"].dispatch(player,
                                                               cmd) == False:
            return False

        # Beyond this point, we deal with events that don't overlap,
        # meaning we can safely return the result of the dispatch method.
        res = _re_say.match(cmd)
        if res:
            msg = res.group("msg").replace("\"", "")
            channel = minqlx.CHAT_CHANNEL
            return minqlx.EVENT_DISPATCHERS["chat"].dispatch(
                player, msg, channel)

        res = _re_say_team.match(cmd)
        if res:
            msg = res.group("msg").replace("\"", "")
            if player.team == "free":  # I haven't tried this, but I don't think it's even possible.
                channel = minqlx.FREE_CHAT_CHANNEL
            elif player.team == "red":
                channel = minqlx.RED_TEAM_CHAT_CHANNEL
            elif player.team == "blue":
                channel = minqlx.BLUE_TEAM_CHAT_CHANNEL
            else:
                channel = minqlx.SPECTATOR_CHAT_CHANNEL
            return minqlx.EVENT_DISPATCHERS["chat"].dispatch(
                player, msg, channel)

        res = _re_callvote.match(cmd)
        if res:
            vote = res.group("cmd")
            args = res.group("args") if res.group("args") else ""
            return minqlx.EVENT_DISPATCHERS["vote_called"].dispatch(
                player, vote, args)

        res = _re_vote.match(cmd)
        if res and minqlx.Plugin.is_vote_active():
            arg = res.group("arg")
            if arg.lower() == "y" or arg == "1":
                return minqlx.EVENT_DISPATCHERS["vote"].dispatch(True)
            elif arg.lower() == "n" or arg == "1":
                return minqlx.EVENT_DISPATCHERS["vote"].dispatch(False)
    except:
        minqlx.log_exception()
        return True
Example #4
0
def handle_player_spawn(client_id):
    """Called when a player spawns. Note that a spectator going in free spectate mode
    makes the client spawn, so you'll want to check for that if you only want "actual"
    spawns.

    """
    try:
        player = minqlx.Player(client_id)
        return minqlx.EVENT_DISPATCHERS["player_spawn"].dispatch(player)
    except:
        minqlx.log_exception()
        return True
Example #5
0
def handle_kamikaze_use(client_id):
    """This will be called whenever player uses kamikaze item.

    :param client_id: The client identifier.
    :type client_id: int

    """
    try:
        player = minqlx.Player(client_id)
        return minqlx.EVENT_DISPATCHERS["kamikaze_use"].dispatch(player)
    except:
        minqlx.log_exception()
        return True
Example #6
0
def handle_player_disconnect(client_id):
    """This will be called whenever a player disconnects.

    :param client_id: The client identifier.
    :type client_id: int

    """
    try:
        player = minqlx.Player(client_id)
        return minqlx.EVENT_DISPATCHERS["player_disconnect"].dispatch(player)
    except:
        minqlx.log_exception()
        return True
Example #7
0
def handle_kamikaze_use(client_id: int):
    """This will be called whenever player uses kamikaze item.

    :param: client_id: The client identifier.
    :type: client_id: int

    """
    # noinspection PyBroadException
    try:
        player = minqlx.Player(client_id)
        return minqlx.EVENT_DISPATCHERS["kamikaze_use"].dispatch(player)
    except:  # pylint: disable=bare-except
        minqlx.log_exception()
        return True
Example #8
0
def handle_player_loaded(client_id):
    """This will be called whenever a player has connected and finished loading,
    meaning it'll go off a bit later than the usual "X connected" messages.
    This will not trigger on bots.

    :param client_id: The client identifier.
    :type client_id: int

    """
    try:
        player = minqlx.Player(client_id)
        return minqlx.EVENT_DISPATCHERS["player_loaded"].dispatch(player)
    except:
        minqlx.log_exception()
        return True
Example #9
0
def handle_player_disconnect(client_id: int, reason: Optional[str]):
    """This will be called whenever a player disconnects.

    :param: client_id: The client identifier.
    :type: client_id: int
    :param: reason: The reason for the disconnect
    :type: reason: str

    """
    # noinspection PyBroadException
    try:
        player = minqlx.Player(client_id)
        return minqlx.EVENT_DISPATCHERS["player_disconnect"].dispatch(
            player, reason)
    except:  # pylint: disable=bare-except
        minqlx.log_exception()
        return True
Example #10
0
def handle_kamikaze_explode(client_id, is_used_on_demand):
    """This will be called whenever kamikaze explodes.

    :param client_id: The client identifier.
    :type client_id: int
    :param is_used_on_demand: Non-zero if kamikaze is used on demand.
    :type is_used_on_demand: int


    """
    try:
        player = minqlx.Player(client_id)
        return minqlx.EVENT_DISPATCHERS["kamikaze_explode"].dispatch(
            player, True if is_used_on_demand else False)
    except:
        minqlx.log_exception()
        return True
Example #11
0
def handle_kamikaze_explode(client_id: int, is_used_on_demand: bool):
    """This will be called whenever kamikaze explodes.

    :param: client_id: The client identifier.
    :type: client_id: int
    :param: is_used_on_demand: Non-zero if kamikaze is used on demand.
    :type: is_used_on_demand: int


    """
    # noinspection PyBroadException
    try:
        player = minqlx.Player(client_id)
        return minqlx.EVENT_DISPATCHERS["kamikaze_explode"].dispatch(
            player, bool(is_used_on_demand))
    except:  # pylint: disable=bare-except
        minqlx.log_exception()
        return True
Example #12
0
def handle_player_connect(client_id, is_bot):
    """This will be called whenever a player tries to connect. If the dispatcher
    returns False, it will not allow the player to connect and instead show them
    a message explaining why. The default message is "You are banned from this
    server.", but it can be set with :func:`minqlx.set_ban_message`.

    :param client_id: The client identifier.
    :type client_id: int
    :param is_bot: Whether or not the player is a bot.
    :type is_bot: bool

    """
    try:
        player = minqlx.Player(client_id)
        return minqlx.EVENT_DISPATCHERS["player_connect"].dispatch(player)
    except:
        minqlx.log_exception()
        return True
Example #13
0
def handle_server_command(client_id, cmd):
    try:
        # Dispatch the "server_command" event before further processing.
        try:
            player = minqlx.Player(client_id) if client_id >= 0 else None
        except minqlx.NonexistentPlayerError:
            return True

        if minqlx.EVENT_DISPATCHERS["server_command"].dispatch(player,
                                                               cmd) == False:
            return False

        res = _re_vote_ended.match(cmd)
        if res:
            if res.group("result") == "passed":
                minqlx.EVENT_DISPATCHERS["vote_ended"].dispatch(True)
            else:
                minqlx.EVENT_DISPATCHERS["vote_ended"].dispatch(False)
            return
    except:
        minqlx.log_exception()
        return True
Example #14
0
def handle_client_command(client_id: int, cmd: str):
    """Client commands are commands such as "say", "say_team", "scores",
    "disconnect" and so on. This function parses those and passes it
    on to the event dispatcher.

    :param: client_id: The client identifier.
    :type: client_id: int
    :param: cmd: The command being run by the client.
    :type: cmd: str

    """
    # noinspection PyBroadException
    try:
        # Dispatch the "client_command" event before further processing.
        player = minqlx.Player(client_id)
        retval = minqlx.EVENT_DISPATCHERS["client_command"].dispatch(
            player, cmd)
        if retval is False:
            return False
        if isinstance(retval, str):
            # Allow plugins to modify the command before passing it on.
            cmd = retval

        res = _re_say.match(cmd)
        if res:
            msg = res.group("msg").replace("\"", "")
            channel = minqlx.CHAT_CHANNEL
            if minqlx.EVENT_DISPATCHERS["chat"].dispatch(player, msg,
                                                         channel) is False:
                return False
            return cmd

        res = _re_say_team.match(cmd)
        if res:
            msg = res.group("msg").replace("\"", "")
            if player.team == "free":  # I haven't tried this, but I don't think it's even possible.
                channel = minqlx.FREE_CHAT_CHANNEL
            elif player.team == "red":
                channel = minqlx.RED_TEAM_CHAT_CHANNEL
            elif player.team == "blue":
                channel = minqlx.BLUE_TEAM_CHAT_CHANNEL
            else:
                channel = minqlx.SPECTATOR_CHAT_CHANNEL
            if minqlx.EVENT_DISPATCHERS["chat"].dispatch(player, msg,
                                                         channel) is False:
                return False
            return cmd

        res = _re_callvote.match(cmd)
        if res and not minqlx.Plugin.is_vote_active():
            vote = res.group("cmd")
            args = res.group("args") if res.group("args") else ""
            # Set the caller for vote_started in case the vote goes through.
            minqlx.EVENT_DISPATCHERS["vote_started"].caller(player)
            if minqlx.EVENT_DISPATCHERS["vote_called"].dispatch(
                    player, vote, args) is False:
                return False
            return cmd

        res = _re_vote.match(cmd)
        if res and minqlx.Plugin.is_vote_active():
            arg = res.group("arg").lower()
            if arg in ["y", "1"]:
                if minqlx.EVENT_DISPATCHERS["vote"].dispatch(player,
                                                             True) is False:
                    return False
            elif arg in ["n", "2"]:
                if minqlx.EVENT_DISPATCHERS["vote"].dispatch(player,
                                                             False) is False:
                    return False
            return cmd

        res = _re_team.match(cmd)
        if res:
            arg = res.group("arg").lower()
            target_team = ""
            if arg == player.team[0]:
                # Don't trigger if player is joining the same team.
                return cmd
            if arg == "f":
                target_team = "free"
            elif arg == "r":
                target_team = "red"
            elif arg == "b":
                target_team = "blue"
            elif arg == "s":
                target_team = "spectator"
            elif arg == "a":
                target_team = "any"

            if target_team:
                if minqlx.EVENT_DISPATCHERS["team_switch_attempt"].dispatch(
                        player, player.team, target_team) is False:
                    return False
            return cmd

        res = _re_userinfo.match(cmd)
        if res:
            new_info = minqlx.parse_variables(res.group("vars"), ordered=True)
            old_info = player.cvars
            changed = {}

            for key in new_info:
                if key not in old_info or (key in old_info
                                           and new_info[key] != old_info[key]):
                    changed[key] = new_info[key]

            if changed:
                ret = minqlx.EVENT_DISPATCHERS["userinfo"].dispatch(
                    player, changed)
                if ret is False:
                    return False
                if isinstance(ret, dict):
                    for key in ret:
                        new_info[key] = ret[key]
                    formatted_key_values = "".join([
                        f"\\{key}\\{value}" for key, value in new_info.items()
                    ])
                    cmd = f"userinfo \"{formatted_key_values}\""

        return cmd
    except:  # pylint: disable=bare-except
        minqlx.log_exception()
        return True