Ejemplo n.º 1
0
 def __call__(self, *args, **kwargs):
     if self.func is None:
         func = args[0]
         if isinstance(func, event_listener):
             func = func.func
         self.func = handle_error(func)
         events.add_listener(self.event, self.func, self.priority)
         self.__doc__ = self.func.__doc__
         return self
     else:
         return self.func(*args, **kwargs)
Ejemplo n.º 2
0
def connect_callback(cli):
    regaincount = 0
    releasecount = 0

    @hook("endofmotd", hookid=294)
    @hook("nomotd", hookid=294)
    def prepare_stuff(cli, prefix, *args):
        alog("Received end of MOTD from {0}".format(prefix))

        # This callback only sets up event listeners
        wolfgame.connect_callback()

        # just in case we haven't managed to successfully auth yet
        if botconfig.PASS and not botconfig.SASL_AUTHENTICATION:
            cli.ns_identify(botconfig.USERNAME or botconfig.NICK,
                            botconfig.PASS,
                            nickserv=var.NICKSERV,
                            command=var.NICKSERV_IDENTIFY_COMMAND)

        channels.Main = channels.add(botconfig.CHANNEL, cli)
        channels.Dummy = channels.add("*", cli)

        if botconfig.ALT_CHANNELS:
            for chan in botconfig.ALT_CHANNELS.split(","):
                channels.add(chan, cli)

        if botconfig.DEV_CHANNEL:
            channels.Dev = channels.add(botconfig.DEV_CHANNEL, cli)

        if var.LOG_CHANNEL:
            channels.add(var.LOG_CHANNEL, cli)

        #if var.CHANSERV_OP_COMMAND: # TODO: Add somewhere else if needed
        #    cli.msg(var.CHANSERV, var.CHANSERV_OP_COMMAND.format(channel=botconfig.CHANNEL))

        users.Bot.change_nick(botconfig.NICK)

        if var.SERVER_PING_INTERVAL > 0:

            def ping_server_timer(cli):
                ping_server(cli)

                t = threading.Timer(var.SERVER_PING_INTERVAL,
                                    ping_server_timer,
                                    args=(cli, ))
                t.daemon = True
                t.start()

            ping_server_timer(cli)

    def setup_handler(evt, var, target):
        target.client.command_handler["privmsg"] = on_privmsg
        target.client.command_handler["notice"] = functools.partial(
            on_privmsg, notice=True)

        events.remove_listener("who_end", setup_handler)

    events.add_listener("who_end", setup_handler)

    def mustregain(cli, server, bot_nick, nick, msg):
        nonlocal regaincount

        if not botconfig.PASS or bot_nick == nick or regaincount > 3:
            return
        if var.NICKSERV_REGAIN_COMMAND:
            cli.ns_regain(nick=botconfig.NICK,
                          password=botconfig.PASS,
                          nickserv=var.NICKSERV,
                          command=var.NICKSERV_REGAIN_COMMAND)
        else:
            cli.ns_ghost(nick=botconfig.NICK,
                         password=botconfig.PASS,
                         nickserv=var.NICKSERV,
                         command=var.NICKSERV_GHOST_COMMAND)
        # it is possible (though unlikely) that regaining the nick fails for some reason and we would loop infinitely
        # as such, keep track of a count of how many times we regain, and after 3 times we no longer attempt to regain nicks
        # Since we'd only be regaining on initial connect, this should be safe. The same trick is used below for release as well
        regaincount += 1
        users.Bot.change_nick(botconfig.NICK)

    def mustrelease(cli, server, bot_nick, nick, msg):
        nonlocal releasecount

        if not botconfig.PASS or bot_nick == nick or releasecount > 3:
            return  # prevents the bot from trying to release without a password
        if var.NICKSERV_RELEASE_COMMAND:
            cli.ns_release(nick=botconfig.NICK,
                           password=botconfig.PASS,
                           nickserv=var.NICKSERV,
                           command=var.NICKSERV_GHOST_COMMAND)
        else:
            cli.ns_ghost(nick=botconfig.NICK,
                         password=botconfig.PASS,
                         nickserv=var.NICKSERV,
                         command=var.NICKSERV_GHOST_COMMAND)
        releasecount += 1
        users.Bot.change_nick(botconfig.NICK)

    @hook("unavailresource", hookid=239)
    @hook("nicknameinuse", hookid=239)
    def must_use_temp_nick(cli, *etc):
        users.Bot.nick += "_"
        users.Bot.change_nick()
        cli.user(botconfig.NICK, "")  # TODO: can we remove this?

        hook.unhook(239)
        hook("unavailresource", hookid=240)(mustrelease)
        hook("nicknameinuse", hookid=241)(mustregain)

    request_caps = {"account-notify", "extended-join", "multi-prefix"}

    if botconfig.SASL_AUTHENTICATION:
        request_caps.add("sasl")

    supported_caps = set()

    @hook("cap")
    def on_cap(cli, svr, mynick, cmd, caps, star=None):
        if cmd == "LS":
            if caps == "*":
                # Multi-line LS
                supported_caps.update(star.split())
            else:
                supported_caps.update(caps.split())

                if botconfig.SASL_AUTHENTICATION and "sasl" not in supported_caps:
                    alog("Server does not support SASL authentication")
                    cli.quit()

                common_caps = request_caps & supported_caps

                if common_caps:
                    cli.send("CAP REQ " ":{0}".format(" ".join(common_caps)))
        elif cmd == "ACK":
            if "sasl" in caps:
                cli.send("AUTHENTICATE PLAIN")
            else:
                cli.send("CAP END")
        elif cmd == "NAK":
            # This isn't supposed to happen. The server claimed to support a
            # capability but now claims otherwise.
            alog("Server refused capabilities: {0}".format(" ".join(caps)))

    if botconfig.SASL_AUTHENTICATION:

        @hook("authenticate")
        def auth_plus(cli, something, plus):
            if plus == "+":
                account = (botconfig.USERNAME
                           or botconfig.NICK).encode("utf-8")
                password = botconfig.PASS.encode("utf-8")
                auth_token = base64.b64encode(b"\0".join(
                    (account, account, password))).decode("utf-8")
                cli.send("AUTHENTICATE " + auth_token)

        @hook("903")
        def on_successful_auth(cli, blah, blahh, blahhh):
            cli.send("CAP END")

        @hook("904")
        @hook("905")
        @hook("906")
        @hook("907")
        def on_failure_auth(cli, *etc):
            alog("Authentication failed.  Did you fill the account name "
                 "in botconfig.USERNAME if it's different from the bot nick?")
            cli.quit()

    users.Bot = users.BotUser(cli, botconfig.NICK)
Ejemplo n.º 3
0
def _reset(evt, var):
    """Cleans up users that left during game during game end."""
    for user in _ghosts:
        if not user.channels:
            _users.discard(user)
    _ghosts.clear()

def _swap_player(evt, var, old_user, user):
    """Mark the user as no longer being a ghost, if they are one."""
    _ghosts.discard(old_user)
    if not old_user.channels:
        _users.discard(old_user)

# Can't use @event_listener decorator since src/decorators.py imports us
# (meaning decorator isn't defined at the point in time we are run)
events.add_listener("cleanup_user", _cleanup_user)
events.add_listener("reset", _reset)
events.add_listener("swap_player", _swap_player, priority=1)

class User(IRCContext):

    is_user = True

    def __new__(cls, cli, nick, ident, host, realname, account):
        self = super().__new__(cls)
        super(__class__, self).__init__(nick, cli)

        self._ident = ident
        self._host = host
        self.realname = realname
        self.account = account
Ejemplo n.º 4
0
    """Return a tuple of (nick, ident, host) from rawnick."""

    return _raw_nick_pattern.search(rawnick).groups(default)

def parse_rawnick_as_dict(rawnick, *, default=None):
    """Return a dict of {"nick": nick, "ident": ident, "host": host}."""

    return _raw_nick_pattern.search(rawnick).groupdict(default)

def _cleanup_user(evt, var, user):
    """Removes a user from our global tracking set once it has left all channels."""
    _users.discard(user)

# Can't use @event_listener decorator since src/decorators.py imports us
# (meaning decorator isn't defined at the point in time we are run)
events.add_listener("cleanup_user", _cleanup_user)

class User(IRCContext):

    is_user = True

    def __new__(cls, cli, nick, ident, host, realname, account):
        self = super().__new__(cls)
        super(__class__, self).__init__(nick, cli)

        self._ident = ident
        self._host = host
        self.realname = realname
        self.account = account
        self.channels = {}
Ejemplo n.º 5
0
    """Removes a user from our global tracking set once it has left all channels."""
    if var.PHASE in var.GAME_PHASES and user in var.ALL_PLAYERS:
        _ghosts.add(user)
    else:
        _users.discard(user)

def _reset(evt, var):
    """Cleans up users that left during game during game end."""
    for user in _ghosts:
        if not user.channels:
            _users.discard(user)
    _ghosts.clear()

# Can't use @event_listener decorator since src/decorators.py imports us
# (meaning decorator isn't defined at the point in time we are run)
events.add_listener("cleanup_user", _cleanup_user)
events.add_listener("reset", _reset)

class User(IRCContext):

    is_user = True

    def __new__(cls, cli, nick, ident, host, realname, account):
        self = super().__new__(cls)
        super(__class__, self).__init__(nick, cli)

        self._ident = ident
        self._host = host
        self.realname = realname
        self.account = account
        self.channels = {}
Ejemplo n.º 6
0
    CLONED[wrapper.source] = target
    wrapper.pm(messages["clone_target_success"].format(target))

    debuglog("{0} (clone) CLONE: {1} ({2})".format(wrapper.source, target,
                                                   get_main_role(target)))


def setup_clone(evt):
    # We need to add "clone" to the role command exceptions so there's no error
    # This is done here so that var isn't imported at the global scope
    # (when we implement proper game state this will be in a different event)
    from src import settings as var
    var.ROLE_COMMAND_EXCEPTIONS.add("clone")


events.add_listener(
    "init", setup_clone)  # no IRC connection, so no possible error handler yet


@event_listener("get_reveal_role")
def on_get_reveal_role(evt, var, user):
    if var.HIDDEN_CLONE and user in var.ORIGINAL_ROLES["clone"]:
        evt.data["role"] = "clone"


@event_listener("del_player")
def on_del_player(evt, var, player, all_roles, death_triggers):
    # clone happens regardless of death_triggers being true or not
    if var.PHASE not in var.GAME_PHASES:
        return

    clones = get_all_players(("clone", ))
Ejemplo n.º 7
0
def connect_callback(cli):
    regaincount = 0
    releasecount = 0

    @hook("endofmotd", hookid=294)
    @hook("nomotd", hookid=294)
    def prepare_stuff(cli, prefix, *args):
        from src import lagcheck
        alog("Received end of MOTD from {0}".format(prefix))

        # This callback only sets up event listeners
        wolfgame.connect_callback()

        # just in case we haven't managed to successfully auth yet
        if botconfig.PASS and not botconfig.SASL_AUTHENTICATION:
            cli.ns_identify(botconfig.USERNAME or botconfig.NICK,
                            botconfig.PASS,
                            nickserv=var.NICKSERV,
                            command=var.NICKSERV_IDENTIFY_COMMAND)

        # don't join any channels if we're just doing a lag check
        if not lagcheck:
            channels.Main = channels.add(botconfig.CHANNEL, cli)
            channels.Dummy = channels.add("*", cli)

            if botconfig.ALT_CHANNELS:
                for chan in botconfig.ALT_CHANNELS.split(","):
                    channels.add(chan, cli)

            if botconfig.DEV_CHANNEL:
                channels.Dev = channels.add(botconfig.DEV_CHANNEL, cli)

            if var.LOG_CHANNEL:
                channels.add(var.LOG_CHANNEL, cli)
        else:
            alog("Preparing lag check")
            # if we ARE doing a lagcheck, we need at least our own host or things break
            users.Bot.who()

        #if var.CHANSERV_OP_COMMAND: # TODO: Add somewhere else if needed
        #    cli.msg(var.CHANSERV, var.CHANSERV_OP_COMMAND.format(channel=botconfig.CHANNEL))

        users.Bot.change_nick(botconfig.NICK)

        if var.SERVER_PING_INTERVAL > 0:
            def ping_server_timer(cli):
                ping_server(cli)

                t = threading.Timer(var.SERVER_PING_INTERVAL, ping_server_timer, args=(cli,))
                t.daemon = True
                t.start()

            ping_server_timer(cli)

    def setup_handler(evt, var, target):
        from src import lagcheck
        if lagcheck: # we just got our own host back
            target.client.command_handler["privmsg"] = on_privmsg
            run_lagcheck(target.client)
        else:
            target.client.command_handler["privmsg"] = on_privmsg
            target.client.command_handler["notice"] = functools.partial(on_privmsg, notice=True)

        events.remove_listener("who_end", setup_handler)

    events.add_listener("who_end", setup_handler)

    def mustregain(cli, server, bot_nick, nick, msg):
        nonlocal regaincount

        if not botconfig.PASS or bot_nick == nick or regaincount > 3:
            return
        if var.NICKSERV_REGAIN_COMMAND:
            cli.ns_regain(nick=botconfig.NICK, password=botconfig.PASS, nickserv=var.NICKSERV, command=var.NICKSERV_REGAIN_COMMAND)
        else:
            cli.ns_ghost(nick=botconfig.NICK, password=botconfig.PASS, nickserv=var.NICKSERV, command=var.NICKSERV_GHOST_COMMAND)
        # it is possible (though unlikely) that regaining the nick fails for some reason and we would loop infinitely
        # as such, keep track of a count of how many times we regain, and after 3 times we no longer attempt to regain nicks
        # Since we'd only be regaining on initial connect, this should be safe. The same trick is used below for release as well
        regaincount += 1
        users.Bot.change_nick(botconfig.NICK)

    def mustrelease(cli, server, bot_nick, nick, msg):
        nonlocal releasecount

        if not botconfig.PASS or bot_nick == nick or releasecount > 3:
            return # prevents the bot from trying to release without a password
        if var.NICKSERV_RELEASE_COMMAND:
            cli.ns_release(nick=botconfig.NICK, password=botconfig.PASS, nickserv=var.NICKSERV, command=var.NICKSERV_GHOST_COMMAND)
        else:
            cli.ns_ghost(nick=botconfig.NICK, password=botconfig.PASS, nickserv=var.NICKSERV, command=var.NICKSERV_GHOST_COMMAND)
        releasecount += 1
        users.Bot.change_nick(botconfig.NICK)

    @hook("unavailresource", hookid=239)
    @hook("nicknameinuse", hookid=239)
    def must_use_temp_nick(cli, *etc):
        users.Bot.nick += "_"
        users.Bot.change_nick()
        cli.user(botconfig.NICK, "") # TODO: can we remove this?

        hook.unhook(239)
        hook("unavailresource", hookid=240)(mustrelease)
        hook("nicknameinuse", hookid=241)(mustregain)

    request_caps = {"account-notify", "extended-join", "multi-prefix", "chghost"}

    if botconfig.SASL_AUTHENTICATION:
        request_caps.add("sasl")

    supported_caps = set()
    supported_sasl = None
    selected_sasl = None

    @hook("cap")
    def on_cap(cli, svr, mynick, cmd, *caps):
        nonlocal supported_sasl, selected_sasl
        # caps is a star because we might receive multiline in LS
        if cmd == "LS":
            for item in caps[-1].split(): # First item may or may not be *, for multiline
                try:
                    key, value = item.split("=", 1)
                except ValueError:
                    key = item
                    value = None
                supported_caps.add(key)
                if key == "sasl" and value is not None:
                    supported_sasl = set(value.split(","))

            if caps[0] == "*": # Multiline, don't continue yet
                return

            if botconfig.SASL_AUTHENTICATION and "sasl" not in supported_caps:
                alog("Server does not support SASL authentication")
                cli.quit()
                raise ValueError("Server does not support SASL authentication")

            common_caps = request_caps & supported_caps

            if common_caps:
                cli.send("CAP REQ " ":{0}".format(" ".join(common_caps)))

        elif cmd == "ACK":
            if "sasl" in caps[0]:
                if var.SSL_CERTFILE:
                    mech = "EXTERNAL"
                else:
                    mech = "PLAIN"
                selected_sasl = mech

                if supported_sasl is None or mech in supported_sasl:
                    cli.send("AUTHENTICATE {0}".format(mech))
                else:
                    alog("Server does not support the SASL {0} mechanism".format(mech))
                    cli.quit()
                    raise ValueError("Server does not support the SASL {0} mechanism".format(mech))
            else:
                cli.send("CAP END")
        elif cmd == "NAK":
            # This isn't supposed to happen. The server claimed to support a
            # capability but now claims otherwise.
            alog("Server refused capabilities: {0}".format(" ".join(caps[0])))

    if botconfig.SASL_AUTHENTICATION:
        @hook("authenticate")
        def auth_plus(cli, something, plus):
            if plus == "+":
                if selected_sasl == "EXTERNAL":
                    cli.send("AUTHENTICATE +")
                elif selected_sasl == "PLAIN":
                    account = (botconfig.USERNAME or botconfig.NICK).encode("utf-8")
                    password = botconfig.PASS.encode("utf-8")
                    auth_token = base64.b64encode(b"\0".join((account, account, password))).decode("utf-8")
                    cli.send("AUTHENTICATE " + auth_token, log="AUTHENTICATE [redacted]")

        @hook("903")
        def on_successful_auth(cli, blah, blahh, blahhh):
            cli.send("CAP END")

        @hook("904")
        @hook("905")
        @hook("906")
        @hook("907")
        def on_failure_auth(cli, *etc):
            nonlocal selected_sasl
            if selected_sasl == "EXTERNAL" and (supported_sasl is None or "PLAIN" in supported_sasl):
                # EXTERNAL failed, retry with PLAIN as we may not have set up the client cert yet
                selected_sasl = "PLAIN"
                alog("EXTERNAL auth failed, retrying with PLAIN... ensure the client cert is set up in NickServ")
                cli.send("AUTHENTICATE PLAIN")
            else:
                alog("Authentication failed.  Did you fill the account name "
                     "in botconfig.USERNAME if it's different from the bot nick?")
                cli.quit()

    users.Bot = users.BotUser(cli, botconfig.NICK)
Ejemplo n.º 8
0
def connect_callback(cli):
    regaincount = 0
    releasecount = 0

    @hook("endofmotd", hookid=294)
    @hook("nomotd", hookid=294)
    def prepare_stuff(cli, prefix, *args):
        from src import lagcheck
        alog("Received end of MOTD from {0}".format(prefix))

        # This callback only sets up event listeners
        wolfgame.connect_callback()

        # just in case we haven't managed to successfully auth yet
        if botconfig.PASS and not botconfig.SASL_AUTHENTICATION:
            cli.ns_identify(botconfig.USERNAME or botconfig.NICK,
                            botconfig.PASS,
                            nickserv=var.NICKSERV,
                            command=var.NICKSERV_IDENTIFY_COMMAND)

        # don't join any channels if we're just doing a lag check
        if not lagcheck:
            channels.Main = channels.add(botconfig.CHANNEL, cli)
            channels.Dummy = channels.add("*", cli)

            if botconfig.ALT_CHANNELS:
                for chan in botconfig.ALT_CHANNELS.split(","):
                    channels.add(chan, cli)

            if botconfig.DEV_CHANNEL:
                channels.Dev = channels.add(botconfig.DEV_CHANNEL, cli)

            if var.LOG_CHANNEL:
                channels.add(var.LOG_CHANNEL, cli)
        else:
            alog("Preparing lag check")
            # if we ARE doing a lagcheck, we need at least our own host or things break
            users.Bot.who()

        #if var.CHANSERV_OP_COMMAND: # TODO: Add somewhere else if needed
        #    cli.msg(var.CHANSERV, var.CHANSERV_OP_COMMAND.format(channel=botconfig.CHANNEL))

        users.Bot.change_nick(botconfig.NICK)

        if var.SERVER_PING_INTERVAL > 0:

            def ping_server_timer(cli):
                ping_server(cli)

                t = threading.Timer(var.SERVER_PING_INTERVAL,
                                    ping_server_timer,
                                    args=(cli, ))
                t.daemon = True
                t.start()

            ping_server_timer(cli)

    def setup_handler(evt, var, target):
        from src import lagcheck
        if lagcheck:  # we just got our own host back
            target.client.command_handler["privmsg"] = on_privmsg
            run_lagcheck(target.client)
        else:
            target.client.command_handler["privmsg"] = on_privmsg
            target.client.command_handler["notice"] = functools.partial(
                on_privmsg, notice=True)

        events.remove_listener("who_end", setup_handler)

    events.add_listener("who_end", setup_handler)

    def mustregain(cli, server, bot_nick, nick, msg):
        nonlocal regaincount

        if not botconfig.PASS or bot_nick == nick or regaincount > 3:
            return
        if var.NICKSERV_REGAIN_COMMAND:
            cli.ns_regain(nick=botconfig.NICK,
                          password=botconfig.PASS,
                          nickserv=var.NICKSERV,
                          command=var.NICKSERV_REGAIN_COMMAND)
        else:
            cli.ns_ghost(nick=botconfig.NICK,
                         password=botconfig.PASS,
                         nickserv=var.NICKSERV,
                         command=var.NICKSERV_GHOST_COMMAND)
        # it is possible (though unlikely) that regaining the nick fails for some reason and we would loop infinitely
        # as such, keep track of a count of how many times we regain, and after 3 times we no longer attempt to regain nicks
        # Since we'd only be regaining on initial connect, this should be safe. The same trick is used below for release as well
        regaincount += 1
        users.Bot.change_nick(botconfig.NICK)

    def mustrelease(cli, server, bot_nick, nick, msg):
        nonlocal releasecount

        if not botconfig.PASS or bot_nick == nick or releasecount > 3:
            return  # prevents the bot from trying to release without a password
        if var.NICKSERV_RELEASE_COMMAND:
            cli.ns_release(nick=botconfig.NICK,
                           password=botconfig.PASS,
                           nickserv=var.NICKSERV,
                           command=var.NICKSERV_GHOST_COMMAND)
        else:
            cli.ns_ghost(nick=botconfig.NICK,
                         password=botconfig.PASS,
                         nickserv=var.NICKSERV,
                         command=var.NICKSERV_GHOST_COMMAND)
        releasecount += 1
        users.Bot.change_nick(botconfig.NICK)

    @hook("unavailresource", hookid=239)
    @hook("nicknameinuse", hookid=239)
    def must_use_temp_nick(cli, *etc):
        users.Bot.nick += "_"
        users.Bot.change_nick()
        cli.user(botconfig.NICK, "")  # TODO: can we remove this?

        hook.unhook(239)
        hook("unavailresource", hookid=240)(mustrelease)
        hook("nicknameinuse", hookid=241)(mustregain)

    request_caps = {
        "account-notify", "extended-join", "multi-prefix", "chghost"
    }

    if botconfig.SASL_AUTHENTICATION:
        request_caps.add("sasl")

    supported_caps = set()
    supported_sasl = None
    selected_sasl = None

    @hook("cap")
    def on_cap(cli, svr, mynick, cmd, *caps):
        nonlocal supported_sasl, selected_sasl
        # caps is a star because we might receive multiline in LS
        if cmd == "LS":
            for item in caps[-1].split(
            ):  # First item may or may not be *, for multiline
                try:
                    key, value = item.split("=", 1)
                except ValueError:
                    key = item
                    value = None
                supported_caps.add(key)
                if key == "sasl" and value is not None:
                    supported_sasl = set(value.split(","))

            if caps[0] == "*":  # Multiline, don't continue yet
                return

            if botconfig.SASL_AUTHENTICATION and "sasl" not in supported_caps:
                alog("Server does not support SASL authentication")
                cli.quit()
                raise ValueError("Server does not support SASL authentication")

            common_caps = request_caps & supported_caps

            if common_caps:
                cli.send("CAP REQ " ":{0}".format(" ".join(common_caps)))

        elif cmd == "ACK":
            if "sasl" in caps[0]:
                if var.SSL_CERTFILE:
                    mech = "EXTERNAL"
                else:
                    mech = "PLAIN"
                selected_sasl = mech

                if supported_sasl is None or mech in supported_sasl:
                    cli.send("AUTHENTICATE {0}".format(mech))
                else:
                    alog("Server does not support the SASL {0} mechanism".
                         format(mech))
                    cli.quit()
                    raise ValueError(
                        "Server does not support the SASL {0} mechanism".
                        format(mech))
            else:
                cli.send("CAP END")
        elif cmd == "NAK":
            # This isn't supposed to happen. The server claimed to support a
            # capability but now claims otherwise.
            alog("Server refused capabilities: {0}".format(" ".join(caps[0])))

    if botconfig.SASL_AUTHENTICATION:

        @hook("authenticate")
        def auth_plus(cli, something, plus):
            if plus == "+":
                if selected_sasl == "EXTERNAL":
                    cli.send("AUTHENTICATE +")
                elif selected_sasl == "PLAIN":
                    account = (botconfig.USERNAME
                               or botconfig.NICK).encode("utf-8")
                    password = botconfig.PASS.encode("utf-8")
                    auth_token = base64.b64encode(b"\0".join(
                        (account, account, password))).decode("utf-8")
                    cli.send("AUTHENTICATE " + auth_token,
                             log="AUTHENTICATE [redacted]")

        @hook("903")
        def on_successful_auth(cli, blah, blahh, blahhh):
            cli.send("CAP END")

        @hook("904")
        @hook("905")
        @hook("906")
        @hook("907")
        def on_failure_auth(cli, *etc):
            nonlocal selected_sasl
            if selected_sasl == "EXTERNAL" and (supported_sasl is None
                                                or "PLAIN" in supported_sasl):
                # EXTERNAL failed, retry with PLAIN as we may not have set up the client cert yet
                selected_sasl = "PLAIN"
                alog(
                    "EXTERNAL auth failed, retrying with PLAIN... ensure the client cert is set up in NickServ"
                )
                cli.send("AUTHENTICATE PLAIN")
            else:
                alog(
                    "Authentication failed.  Did you fill the account name "
                    "in botconfig.USERNAME if it's different from the bot nick?"
                )
                cli.quit()

    users.Bot = users.BotUser(cli, botconfig.NICK)
Ejemplo n.º 9
0
Archivo: cats.py Proyecto: lykoss/lykos
        if len(cats & {"Wolfteam", "Village", "Neutral", "Hidden"}) != 1:
            raise RuntimeError("Invalid categories for {0}: Must have exactly one of {{Wolfteam, Village, Neutral, Hidden}}, got {1}".format(role, cats))
        ROLES[role] = frozenset(cats)
        for cat in cats:
            if cat not in ROLE_CATS:
                raise ValueError("{0!r} is not a valid role category".format(cat))
            globals()[cat.replace(" ", "_")]._roles.add(role)
        All._roles.add(role)

    for cat in ROLE_CATS:
        cls = globals()[cat.replace(" ", "_")]
        cls._roles = frozenset(cls._roles)
    All._roles = frozenset(All._roles)
    FROZEN = True

events.add_listener("init", register_roles, 1)

class Category:
    """Base class for role categories."""

    def __init__(self, name):
        self.name = name
        self._roles = set()

    def __len__(self):
        if not FROZEN:
            raise RuntimeError("Fatal: Role categories are not ready")
        return len(self._roles)

    def __iter__(self):
        if not FROZEN:
Ejemplo n.º 10
0
        ROLES[role] = frozenset(cats)
        for cat in cats:
            if cat not in ROLE_CATS:
                raise ValueError(
                    "{0!r} is not a valid role category".format(cat))
            globals()[cat.replace(" ", "_")]._roles.add(role)
        All._roles.add(role)

    for cat in ROLE_CATS:
        cls = globals()[cat.replace(" ", "_")]
        cls._roles = frozenset(cls._roles)
    All._roles = frozenset(All._roles)
    FROZEN = True


events.add_listener("init", register_roles, 1)


class Category:
    """Base class for role categories."""
    def __init__(self, name):
        self.name = name
        self._roles = set()

    def __len__(self):
        if not FROZEN:
            raise RuntimeError("Fatal: Role categories are not ready")
        return len(self._roles)

    def __iter__(self):
        if not FROZEN:
Ejemplo n.º 11
0
 def startup(self):
     events.add_listener("chk_win", self.chk_win, 1)
Ejemplo n.º 12
0
 def startup(self):
     events.add_listener("role_attribution", self.role_attribution, 1)