Ejemplo n.º 1
0
    def cmd_clan(self, player, msg, channel):
        index = 529 + player.id
        tag_key = _tag_key.format(player.steam_id)
        
        if len(msg) < 2:
            if tag_key in self.db:
                del self.db[tag_key]
                cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True)
                del cs["cn"]
                del cs["xcn"]
                new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs]).lstrip("\\")
                minqlx.set_configstring(index, new_cs)
                player.tell("The clan tag has been cleared.")
            else:
                player.tell("Usage to set a clan tag: ^4{} <clan_tag>".format(msg[0]))
            return minqlx.RET_STOP_EVENT

        if len(self.clean_text(msg[1])) > 5:
            player.tell("The clan tag can only be at most 5 characters long, excluding colors.")
            return minqlx.RET_STOP_EVENT
        
        # If the player already has a clan, we need to edit the current
        # configstring. We can't just append cn and xcn.
        tag = self.clean_tag(msg[1])
        cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True)
        cs["xcn"] = tag
        cs["cn"] = tag
        new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs])
        minqlx.set_configstring(index, new_cs)
        self.db[tag_key] = tag
        self.msg("{} changed clan tag to {}".format(player, tag))
        return minqlx.RET_STOP_EVENT
Ejemplo n.º 2
0
    def cmd_clan(self, player, msg, channel):
        index = 529 + player.id
        tag_key = _tag_key.format(player.steam_id)
        
        if len(msg) < 2:
            if tag_key in self.db:
                del self.db[tag_key]
                cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True)
                del cs["cn"]
                del cs["xcn"]
                new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs]).lstrip("\\")
                minqlx.set_configstring(index, new_cs)
                player.tell("The clan tag has been cleared.")
            else:
                player.tell("Usage to set a clan tag: ^6{} <clan_tag>".format(msg[0]))
            return minqlx.RET_STOP_EVENT

        if len(self.clean_text(msg[1])) > 5:
            player.tell("The clan tag can only be at most 5 characters long, excluding colors.")
            return minqlx.RET_STOP_EVENT
        
        # If the player already has a clan, we need to edit the current
        # configstring. We can't just append cn and xcn.
        tag = self.clean_tag(msg[1])
        cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True)
        cs["xcn"] = tag
        cs["cn"] = tag
        new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs])
        minqlx.set_configstring(index, new_cs)
        self.db[tag_key] = tag
        self.msg("{} changed clan tag to {}".format(player, tag))
        return minqlx.RET_STOP_EVENT
Ejemplo n.º 3
0
def handle_set_configstring(index, value):
    """Called whenever the server tries to set a configstring. Can return
    False to stop the event.

    """
    try:
        res = minqlx.EVENT_DISPATCHERS["set_configstring"].dispatch(index, value)
        if res == False:
            return False
        elif isinstance(res, str):
            value = res

        # GAME STATE CHANGES
        if index == 0:
            old_cs = minqlx.parse_variables(minqlx.get_configstring(index))
            if not old_cs:
                return

            new_cs = minqlx.parse_variables(value)
            old_state = old_cs["g_gameState"]
            new_state = new_cs["g_gameState"]
            if old_state != new_state:
                if old_state == "PRE_GAME" and new_state == "IN_PROGRESS":
                    minqlx.EVENT_DISPATCHERS["vote_ended"].cancel()  # Cancel current vote if any.
                    # minqlx.EVENT_DISPATCHERS["game_start"].dispatch()
                elif old_state == "PRE_GAME" and new_state == "COUNT_DOWN":
                    minqlx.EVENT_DISPATCHERS["game_countdown"].dispatch()
                elif old_state == "COUNT_DOWN" and new_state == "IN_PROGRESS":
                    minqlx.EVENT_DISPATCHERS["vote_ended"].cancel()  # Cancel current vote if any.
                    # minqlx.EVENT_DISPATCHERS["game_start"].dispatch()
                elif old_state == "IN_PROGRESS" and new_state == "PRE_GAME":
                    pass
                elif old_state == "COUNT_DOWN" and new_state == "PRE_GAME":
                    pass
                else:
                    logger = minqlx.get_logger()
                    logger.warning("UNKNOWN GAME STATES: {} - {}".format(old_state, new_state))

        # ROUND COUNTDOWN AND START
        if index == 661:
            cvars = minqlx.parse_variables(value)
            if cvars:
                round_number = int(cvars["round"])
                if round_number and "time" in cvars:
                    if round_number == 1:  # This is the case when the first countdown starts.
                        minqlx.EVENT_DISPATCHERS["round_countdown"].dispatch(round_number)
                        return

                    minqlx.EVENT_DISPATCHERS["round_countdown"].dispatch(round_number)
                    return
                elif round_number:
                    minqlx.EVENT_DISPATCHERS["round_start"].dispatch(round_number)
                    return

        return res
    except:
        minqlx.log_exception()
        return True
Ejemplo n.º 4
0
def _players():
    """A wrapper for minqlx.Players to make the output more usable."""
    ret = []
    for player in minqlx.players_info():
        d = {}
        for key in player:
            if key == "configstring":
                d.update(minqlx.parse_variables(player["configstring"]))
            elif key == "userinfo":
                d.update(minqlx.parse_variables(player["userinfo"]))
            else:
                d[key] = player[key]
        ret.append(d)
    return ret
Ejemplo n.º 5
0
def _players():
    """A wrapper for minqlx.Players to make the output more usable."""
    ret = []
    for player in minqlx.players_info():
        d = {}
        for key in player:
            if key == "configstring":
                d.update(minqlx.parse_variables(player["configstring"]))
            elif key == "userinfo":
                d.update(minqlx.parse_variables(player["userinfo"]))
            else:
                d[key] = player[key]
        ret.append(d)
    return ret
Ejemplo n.º 6
0
def _player(client_id):
    """A wrapper for minqlx.Player to make the output more usable."""
    info = minqlx.player_info(client_id)
    if info == None:
        return None
    
    d = {}
    for key in info:
        if key == "configstring":
            d.update(minqlx.parse_variables(info["configstring"]))
        elif key == "userinfo":
            d.update(minqlx.parse_variables(info["userinfo"]))
        else:
            d[key] = info[key]
    return d
Ejemplo n.º 7
0
def _player(client_id):
    """A wrapper for minqlx.Player to make the output more usable."""
    info = minqlx.player_info(client_id)
    if info == None:
        return None

    d = {}
    for key in info:
        if key == "configstring":
            d.update(minqlx.parse_variables(info["configstring"]))
        elif key == "userinfo":
            d.update(minqlx.parse_variables(info["userinfo"]))
        else:
            d[key] = info[key]
    return d
Ejemplo n.º 8
0
    def handle_configstring(self, index, value):
        if not value:
            return

        elif 529 <= index < 529 + 64:
            try:
                player = self.player(index - 529)
            except minqlx.NonexistentPlayerError:
                return

            if player.steam_id in self._tags:
                tag = self._tags[player.steam_id]

                tag_key = _tag_key.format(player.steam_id)
                if tag_key in self.db:
                    if len(tag) > 0:
                        tag += ' '
                    tag += self.db[tag_key]

                cs = minqlx.parse_variables(value, ordered=True)
                cs["xcn"] = tag
                cs["cn"] = tag
                new_cs = "".join(
                    ["\\{}\\{}".format(key, cs[key]) for key in cs])
                return new_cs
Ejemplo n.º 9
0
 def clan(self, tag):
     index = self.id + 529
     cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True)
     cs["xcn"] = tag
     cs["cn"] = tag
     new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs])
     minqlx.set_configstring(index, new_cs)
Ejemplo n.º 10
0
    def __init__(self, client_id, info=None):
        self._valid = True

        # Can pass own info for efficiency when getting all players and to allow dummy players.
        if info:
            self._id = client_id
            self._info = info
        else:
            self._id = client_id
            self._info = minqlx.player_info(client_id)
            if not self._info:
                self._invalidate(
                    f"Tried to initialize a Player instance of nonexistant player {client_id}."
                )

        self._userinfo = None
        self._steam_id = self._info.steam_id

        # When a player connects, the name field in the client struct has yet to be initialized,
        # so we fall back to the userinfo and try parse it ourselves to get the name if needed.
        if self._info.name:
            self._name = self._info.name
        else:
            self._userinfo = minqlx.parse_variables(self._info.userinfo,
                                                    ordered=True)
            if "name" in self._userinfo:
                self._name = self._userinfo["name"]
            else:  # No name at all. Weird userinfo during connection perhaps?
                self._name = ""
Ejemplo n.º 11
0
 def handle_configstring(self, index, value):
     if not value:
         return
     
     elif 529 <= index < 529 + 64:
         try:
             player = self.player(index - 529)
         except minqlx.NonexistentPlayerError:
             return
         
         if player.steam_id in self._tags:
             tag = self._tags[player.steam_id]
                 
             tag_key = _tag_key.format(player.steam_id)
             if tag_key in self.db:
                 if len(tag) > 0:
                     tag += ' '
                 tag += self.db[tag_key]
                 
                 
             cs = minqlx.parse_variables(value, ordered=True)
             cs["xcn"] = tag
             cs["cn"] = tag
             new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs])
             return new_cs
Ejemplo n.º 12
0
    def __init__(self, client_id, info=None):
        self._valid = True

        # Can pass own info for efficiency when getting all players and to allow dummy players.
        if info:
            self._id = client_id
            self._info = info
        else:
            self._id = client_id
            self._info = minqlx.player_info(client_id)
            if not self._info:
                self._invalidate("Tried to initialize a Player instance of nonexistant player {}."
                    .format(client_id))

        self._userinfo = None
        self._steam_id = self._info.steam_id

        # When a player connects, a the name field in the client struct has yet to be initialized,
        # so we fall back to the userinfo and try parse it ourselves to get the name if needed.
        if self._info.name:
            self._name = self._info.name
        else:
            self._userinfo = minqlx.parse_variables(self._info.userinfo, ordered=True)
            if "name" in self._userinfo:
                self._name = self._userinfo["name"]
            else: # No name at all. Weird userinfo during connection perhaps?
                self._name = ""
Ejemplo n.º 13
0
    def cmd_name(self, player, msg, channel):
        name_key = _name_key.format(player.steam_id)

        if len(msg) < 2:
            if name_key not in self.db:
                return minqlx.RET_USAGE
            else:
                del self.db[name_key]
                player.tell("Your registered name has been removed.")
                return minqlx.RET_STOP_EVENT

        name = self.clean_excessive_colors(" ".join(msg[1:]))
        if len(name.encode()) > 36:
            player.tell("The name is too long. Consider using fewer colors or a shorter name.")
            return minqlx.RET_STOP_EVENT
        elif self.clean_text(name) != player.clean_name and self.get_cvar("qlx_enforceSteamName", bool):
            player.tell("The colored name must match your current Steam name.")
            return minqlx.RET_STOP_EVENT

        info = minqlx.parse_variables(minqlx.player_info(player.id)["userinfo"], ordered=True)
        info["name"] = name
        new_info = "".join(["\\{}\\{}".format(key, info[key]) for key in info])
        minqlx.client_command(player.id, 'userinfo "{}"'.format(new_info))
        self.db[name_key] = name
        player.tell(
            "The name has been registered. To make me forget about it, a simple ^6{}name^7 will do it.".format(
                self.get_cvar("qlx_commandPrefix")
            )
        )
        return minqlx.RET_STOP_EVENT
Ejemplo n.º 14
0
 def clan(self, tag):
     index = self.id + 529
     cs = minqlx.parse_variables(minqlx.get_configstring(index), ordered=True)
     cs["xcn"] = tag
     cs["cn"] = tag
     new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs])
     minqlx.set_configstring(index, new_cs)
Ejemplo n.º 15
0
 def clan(self):
     """The clan tag. Not actually supported by QL, but it used to be and
     fortunately the scoreboard still properly displays it if we manually
     set the configstring to use clan tags."""
     try:
         return minqlx.parse_variables(minqlx.get_configstring(529 + self._id))["cn"]
     except KeyError:
         return ""
Ejemplo n.º 16
0
    def cvars(self):
        if not self._valid:
            self._invalidate()

        if not self._userinfo:
            self._userinfo = minqlx.parse_variables(self._info.userinfo, ordered=True)
        
        return self._userinfo.copy()
Ejemplo n.º 17
0
    def cvars(self):
        if not self._valid:
            self._invalidate()

        if not self._userinfo:
            self._userinfo = minqlx.parse_variables(self._info.userinfo, ordered=True)

        return self._userinfo.copy()
Ejemplo n.º 18
0
 def clan(self):
     """The clan tag. Not actually supported by QL, but it used to be and
     fortunately the scoreboard still properly displays it if we manually
     set the configstring to use clan tags."""
     try:
         return minqlx.parse_variables(minqlx.get_configstring(529 + self._id))["cn"]
     except KeyError:
         return ""
Ejemplo n.º 19
0
    def __contains__(self, key: str) -> bool:
        cs = minqlx.get_configstring(0)
        if not cs:
            self._valid = False
            raise NonexistentGameError("Invalid game. Is the server loading a new map?")

        cvars = minqlx.parse_variables(cs)
        return key in cvars
Ejemplo n.º 20
0
    def __getitem__(self, key):
        cs = minqlx.get_configstring(0)
        if not cs:
            self._valid = False
            raise NonexistentGameError("Invalid game. Is the server loading a new map?")

        cvars = minqlx.parse_variables(cs)
        return cvars[key]
Ejemplo n.º 21
0
    def __getitem__(self, key):
        cs = minqlx.get_configstring(0)
        if not cs:
            self._valid = False
            raise NonexistentGameError("Invalid game. Is the server loading a new map?")

        cvars = minqlx.parse_variables(cs)
        return cvars[key]
Ejemplo n.º 22
0
 def handle_player_loaded(self, player):
     name_key = _name_key.format(player.steam_id)
     if name_key in self.db:
         db_name = self.db[name_key]
         if not self.get_cvar("qlx_enforceSteamName", bool) or self.clean_text(db_name) == player.clean_name:
             info = minqlx.parse_variables(minqlx.player_info(player.id)["userinfo"], ordered=True)
             info["name"] = db_name
             new_info = "".join(["\\{}\\{}".format(key, info[key]) for key in info])
             minqlx.client_command(player.id, 'userinfo "{}"'.format(new_info))
Ejemplo n.º 23
0
    def update(self):
        """Update the player information with the latest data. If the player
        disconnected it will raise an exception and invalidates a player.
        The player's name and Steam ID can still be accessed after being
        invalidated, but anything else will make it throw an exception too.

        :raises: minqlx.NonexistentPlayerError

        """
        self._info = minqlx.player_info(self._id)

        if not self._info or self._steam_id != self._info.steam_id:
            self._invalidate()

        if self._info.name:
            self._name = self._info.name
        else:
            self._userinfo = minqlx.parse_variables(self._info.userinfo, ordered=True)
            if "name" in self._userinfo:
                self._name = self._userinfo["name"]
            else:
                self._name = ""
Ejemplo n.º 24
0
    def update(self):
        """Update the player information with the latest data. If the player
        disconnected it will raise an exception and invalidates a player.
        The player's name and Steam ID can still be accessed after being 
        invalidated, but anything else will make it throw an exception too.

        :raises: minqlx.NonexistentPlayerError

        """
        self._info = minqlx.player_info(self._id)

        if not self._info or self._steam_id != self._info.steam_id:
            self._invalidate()

        if self._info.name:
            self._name = self._info.name
        else:
            self._userinfo = minqlx.parse_variables(self._info.userinfo, ordered=True)
            if "name" in self._userinfo:
                self._name = self._userinfo["name"]
            else:
                self._name = ""
Ejemplo n.º 25
0
 def name(self, value):
     info = minqlx.parse_variables(minqlx.get_userinfo(self.id), ordered=True)
     info["name"] = value
     new_info = "\\".join(["{}\\{}".format(key, info[key]) for key in info])
     minqlx.client_command(self.id, 'userinfo "{}"'.format(new_info))
     self._name = value
Ejemplo n.º 26
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)
        retval = minqlx.EVENT_DISPATCHERS["client_command"].dispatch(player, cmd)
        if retval == False:
            return False
        elif 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) == 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) == 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 ""
            if minqlx.EVENT_DISPATCHERS["vote_called"].dispatch(player, vote, args) == 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 == "y" or arg == "1":
                if minqlx.EVENT_DISPATCHERS["vote"].dispatch(player, True) == False:
                    return False
            elif arg == "n" or arg == "2":
                if minqlx.EVENT_DISPATCHERS["vote"].dispatch(player, False) == 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
            elif 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) == 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 == False:
                    return False
                elif isinstance(ret, dict):
                    for key in ret:
                        new_info[key] = ret[key]
                    cmd = "userinfo \"{}\"".format("".join(["\\{}\\{}".format(key, new_info[key]) for key in new_info]))

        return cmd
    except:
        minqlx.log_exception()
        return True
 def set_player_configstring(self, player, index, key, value): # will let you set a configstring on a per-player basis.
     original_configstring = minqlx.parse_variables(minqlx.get_configstring(index))
     original_configstring[key] = value
     modified_configstring = (("\\") + ("\\".join("\\".join((k,str(v))) for k,v in sorted(original_configstring.items()))))
     minqlx.send_server_command(player.id, "cs {} {}".format(index, modified_configstring))
Ejemplo n.º 28
0
    def cvars(self):
        """A dictionary of unprocessed cvars. Use attributes whenever possible, but since some
        cvars might not have attributes on this class, this could be useful.

        """
        return minqlx.parse_variables(minqlx.get_configstring(0))
Ejemplo n.º 29
0
    def cmd_clan(self, player, msg, channel):
        index = 529 + player.id
        tag_key = _tag_key.format(player.steam_id)

        if len(msg) < 2:
            if tag_key in self.db:
                del self.db[tag_key]
                cs = minqlx.parse_variables(minqlx.get_configstring(index),
                                            ordered=True)
                del cs["cn"]
                del cs["xcn"]
                new_cs = "".join([
                    "\\{}\\{}".format(key, cs[key]) for key in cs
                ]).lstrip("\\")
                minqlx.set_configstring(index, new_cs)
                player.tell("^3The clan tag has been cleared.")
            else:
                player.tell(
                    "^3Usage to set a clan tag: ^6{} <clan_tag>".format(
                        msg[0]))
            return minqlx.RET_STOP_EVENT

        cleanTag = self.clean_text(msg[1])
        if len(cleanTag) > 5:
            player.tell(
                "^3The clan tag can only be at most 5 characters long, excluding colors."
            )
            return minqlx.RET_STOP_EVENT

        tag = self.clean_tag(msg[1])

        #The clan tag being added is checked if the player is not in the clan members list.
        if player.steam_id not in self.clanTagMembers:
            colors = self.get_cvar("qlx_clanmembersTagColors", bool)
            case = self.get_cvar("qlx_clanmembersLetterCase", bool)
            #Checks the tag if tag enforcement is not color or case specific.
            if not colors and not case:
                tempList = []
                for tags in self.clanTag:
                    tempList.append(self.clean_text(tags).lower())
                if cleanTag.lower() in tempList:
                    player.tell(
                        "^3You must be added to the clan members list to put that tag on in this server."
                    )
                    return minqlx.RET_STOP_EVENT
            #Checks the tag if tag enforcement is not color specific but is case specific.
            elif not colors:
                tempList = []
                for tags in self.clanTag:
                    tempList.append(self.clean_text(tags))
                if cleanTag in tempList:
                    player.tell(
                        "^3You must be added to the clan members list to put that tag on in this server."
                    )
                    return minqlx.RET_STOP_EVENT
            #Checks the tag if tag enforcement is not case specific but is color specific.
            elif not case:
                tempList = []
                for tags in self.clanTag:
                    tempList.append(tags.lower())
                if tag.lower() in tempList:
                    player.tell(
                        "^3You must be added to the clan members list to put that tag on in this server."
                    )
                    return minqlx.RET_STOP_EVENT
            #Checks the tag if tag enforcement is case and color specific.
            elif cleanTag in self.clanTag or tag in self.clanTag:
                player.tell(
                    "^3You must be added to the clan members list to put that tag on in this server."
                )
                return minqlx.RET_STOP_EVENT

        # If the player already has a clan, we need to edit the current
        # configstring. We can't just append cn and xcn.
        cs = minqlx.parse_variables(minqlx.get_configstring(index),
                                    ordered=True)
        cs["xcn"] = tag
        cs["cn"] = tag
        new_cs = "".join(["\\{}\\{}".format(key, cs[key]) for key in cs])
        minqlx.set_configstring(index, new_cs)
        self.db[tag_key] = tag
        self.msg("{} changed clan tag to {}".format(player, tag))
        return minqlx.RET_STOP_EVENT
Ejemplo n.º 30
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
Ejemplo n.º 31
0
def handle_set_configstring(index: int, value: str):  # pylint: disable=inconsistent-return-statements
    """Called whenever the server tries to set a configstring. Can return
    False to stop the event.

    """
    global _ad_round_number  # pylint: disable=global-statement

    # noinspection PyBroadException
    try:
        res = minqlx.EVENT_DISPATCHERS["set_configstring"].dispatch(
            index, value)
        if res is False:
            return False
        if isinstance(res, str):
            value = res

        # VOTES
        if index == 9 and value:
            cmd = value.split()
            vote = cmd[0] if cmd else ""
            args = " ".join(cmd[1:]) if len(cmd) > 1 else ""
            minqlx.EVENT_DISPATCHERS["vote_started"].dispatch(vote, args)
            return
        # GAME STATE CHANGES
        if index == 0:
            old_cs = minqlx.parse_variables(minqlx.get_configstring(index))
            if not old_cs:
                return

            new_cs = minqlx.parse_variables(value)
            old_state = old_cs["g_gameState"]
            new_state = new_cs["g_gameState"]
            if old_state != new_state:
                if old_state == "PRE_GAME" and new_state == "IN_PROGRESS":
                    pass
                elif old_state == "PRE_GAME" and new_state == "COUNT_DOWN":
                    _ad_round_number = 1
                    minqlx.EVENT_DISPATCHERS["game_countdown"].dispatch()
                elif old_state == "COUNT_DOWN" and new_state == "IN_PROGRESS":
                    pass
                    # minqlx.EVENT_DISPATCHERS["game_start"].dispatch()
                elif old_state == "IN_PROGRESS" and new_state == "PRE_GAME":
                    pass
                elif old_state == "COUNT_DOWN" and new_state == "PRE_GAME":
                    pass
                else:
                    logger = minqlx.get_logger()
                    logger.warning(
                        f"UNKNOWN GAME STATES: {old_state} - {new_state}")
        # ROUND COUNTDOWN AND START
        elif index == 661:
            cvars = minqlx.parse_variables(value)
            if cvars:
                if "turn" in cvars:
                    # it is A&D
                    if int(cvars["state"]) == 0:
                        return
                    # round cvar appears only on round countdown
                    # and first round is 0, not 1
                    try:
                        round_number = int(cvars["round"]) * 2 + 1 + int(
                            cvars["turn"])
                        _ad_round_number = round_number
                    except KeyError:
                        round_number = _ad_round_number
                else:
                    # it is CA
                    round_number = int(cvars["round"])

                if round_number and "time" in cvars:
                    minqlx.EVENT_DISPATCHERS["round_countdown"].dispatch(
                        round_number)
                    return
                if round_number:
                    minqlx.EVENT_DISPATCHERS["round_start"].dispatch(
                        round_number)
                    return

        return res
    except:  # pylint: disable=bare-except
        minqlx.log_exception()
        return True
Ejemplo n.º 32
0
def handle_set_configstring(index, value):
    """Called whenever the server tries to set a configstring. Can return
    False to stop the event.

    """
    try:
        res = minqlx.EVENT_DISPATCHERS["set_configstring"].dispatch(
            index, value)
        if res == False:
            return False
        elif isinstance(res, str):
            value = res

        # GAME STATE CHANGES
        if index == 0:
            old_cs = minqlx.parse_variables(minqlx.get_configstring(index))
            if not old_cs:
                return

            new_cs = minqlx.parse_variables(value)
            old_state = old_cs["g_gameState"]
            new_state = new_cs["g_gameState"]
            if old_state != new_state:
                if old_state == "PRE_GAME" and new_state == "IN_PROGRESS":
                    minqlx.EVENT_DISPATCHERS["vote_ended"].cancel(
                    )  # Cancel current vote if any.
                    #minqlx.EVENT_DISPATCHERS["game_start"].dispatch()
                elif old_state == "PRE_GAME" and new_state == "COUNT_DOWN":
                    minqlx.EVENT_DISPATCHERS["game_countdown"].dispatch()
                elif old_state == "COUNT_DOWN" and new_state == "IN_PROGRESS":
                    minqlx.EVENT_DISPATCHERS["vote_ended"].cancel(
                    )  # Cancel current vote if any.
                    #minqlx.EVENT_DISPATCHERS["game_start"].dispatch()
                elif old_state == "IN_PROGRESS" and new_state == "PRE_GAME":
                    pass
                elif old_state == "COUNT_DOWN" and new_state == "PRE_GAME":
                    pass
                else:
                    logger = minqlx.get_logger()
                    logger.warning("UNKNOWN GAME STATES: {} - {}".format(
                        old_state, new_state))

        # ROUND COUNTDOWN AND START
        if index == 661:
            cvars = minqlx.parse_variables(value)
            if cvars:
                round_number = int(cvars["round"])
                if round_number and "time" in cvars:
                    if round_number == 1:  # This is the case when the first countdown starts.
                        minqlx.EVENT_DISPATCHERS["round_countdown"].dispatch(
                            round_number)
                        return

                    minqlx.EVENT_DISPATCHERS["round_countdown"].dispatch(
                        round_number)
                    return
                elif round_number:
                    minqlx.EVENT_DISPATCHERS["round_start"].dispatch(
                        round_number)
                    return

        return res
    except:
        minqlx.log_exception()
        return True
Ejemplo n.º 33
0
    def cvars(self):
        """A dictionary of unprocessed cvars. Use attributes whenever possible, but since some
        cvars might not have attributes on this class, this could be useful.

        """
        return minqlx.parse_variables(minqlx.get_configstring(0))
Ejemplo n.º 34
0
 def name(self, value):
     info = minqlx.parse_variables(minqlx.get_userinfo(self.id), ordered=True)
     info["name"] = value
     new_info = "\\".join(["{}\\{}".format(key, info[key]) for key in info])
     minqlx.client_command(self.id, "userinfo \"{}\"".format(new_info))
     self._name = value