Example #1
0
 def handle_quit(self, _, e):
     # Log quits.
     for channel in misc.get_channels(self.channels, e.source.nick):
         self.handler.do_log(channel, e.source, e.arguments[0], 'quit')
     # If we're the one quiting, shut things down cleanly.
     if e.source.nick == self.connection.real_nickname:
         # FIXME: If this hangs or takes more then 5 seconds, we'll just reconnect.
         self.shutdown_mp()
         sys.exit(0)
Example #2
0
 def handle_quit(self, _, e):
     # Log quits.
     for channel in misc.get_channels(self.channels, e.source.nick):
         self.handler.do_log(channel, e.source, e.arguments[0], 'quit')
     # If we're the one quiting, shut things down cleanly.
     if e.source.nick == self.connection.real_nickname:
         # FIXME: If this hangs or takes more then 5 seconds, we'll just reconnect.
         self.shutdown_mp()
         sys.exit(0)
Example #3
0
 def handle_event(self, msg, send, c, e):
     passwd = self.config['auth']['serverpass']
     user = self.config['core']['nick']
     # The SASL Successful event doesn't have a pretty name.
     if e.type == '903':
         if msg == 'SASL authentication successful':
             self.connection.cap('END')
     elif e.type == 'authenticate':
         if e.target == '+':
             token = base64.b64encode('\0'.join([user, user, passwd]).encode())
             self.connection.send_raw('AUTHENTICATE %s' % token.decode())
     elif e.type == 'bannedfromchan':
         self.workers.defer(5, False, self.do_rejoin, c, e)
     elif e.type == 'cap':
         if msg == 'ACK sasl':
             self.connection.send_raw('AUTHENTICATE PLAIN')
     elif e.type in ['ctcpreply', 'nosuchnick']:
         misc.ping(self.ping_map, c, e, time.time())
     elif e.type == 'error':
         logging.error(e.target)
     elif e.type == 'nick':
         for channel in misc.get_channels(self.channels, e.target):
             self.do_log(channel, e.source.nick, e.target, 'nick')
         if self.config.getboolean('feature', 'nickserv') and e.target in self.admins:
             c.privmsg('NickServ', 'ACC %s' % e.target)
         if identity.handle_nick(self, e):
             for x in misc.get_channels(self.channels, e.target):
                 self.do_kick(send, x, e.target, "identity crisis")
     elif e.type == 'nicknameinuse':
         self.connection.nick('Guest%d' % random.getrandbits(20))
         if self.config.getboolean('feature', 'nickserv'):
             self.connection.privmsg('NickServ', 'REGAIN %s %s' % (user, passwd))
         self.workers.defer(5, False, self.do_welcome)
     elif e.type == 'privnotice':
         # FIXME: come up with a better way to prevent admin abuse.
         if e.source.nick == 'NickServ':
             admin.set_admin(msg, self)
     elif e.type == 'welcome':
         logging.info("Connected to server %s", self.config['core']['host'])
         self.do_welcome()
Example #4
0
 def handle_quit(self, c, e):
     """Log quits."""
     for channel in misc.get_channels(self.channels, e.source.split('!')[0]):
         self.handler.do_log(channel, e.source, e.arguments[0], 'quit')
Example #5
0
 def on_nick(self, c, e):
     """Log nick changes."""
     for channel in misc.get_channels(self.channels, e.target):
         self.handler.do_log(channel, e.source.nick, e.target, 'nick')
     self.handle_msg('nick', c, e)
Example #6
0
    def handle_msg(self, msgtype, c, e):
        """The Heart and Soul of IrcBot."""

        # actions don't have the nick attr for some reason
        if msgtype == 'action':
            nick = e.source.split('!')[0]
        else:
            nick = e.source.nick

        # modes have separate arguments, everything else just one
        if msgtype == 'mode' or msgtype == 'nick' or msgtype == 'join':
            msg = " ".join(e.arguments)
        else:
            msg = e.arguments[0].strip()

        # Send the response to private messages to the sending nick.
        if msgtype == 'privmsg' or msgtype == 'privnotice':
            target = nick
        else:
            target = e.target

        send = lambda msg, mtype='privmsg', target=target: self.send(target, self.config['core']['nick'], msg, mtype)

        if msgtype == 'privnotice':
            if not hasattr(self, 'connection'):
                return
            if nick == 'NickServ':
                admin.set_admin(msg, self)
                return

        if self.config['feature'].getboolean('hooks') and nick not in self.ignored:
            for hook in self.hooks:
                realargs = self.do_args(hook.args, send, nick, target, e.source, c, hook, msgtype)
                hook.run(send, msg, msgtype, self, target, realargs)

        if msgtype == 'nick':
            if e.target in self.admins:
                c.privmsg('NickServ', 'ACC %s' % e.target)
            if identity.handle_nick(self, e):
                for x in misc.get_channels(self.channels, e.target):
                    self.do_kick(send, x, e.target, "identity crisis")
            return

        # must come after set_admin to prevent spam
        self.do_log(target, nick, msg, msgtype)

        if msgtype == 'mode':
            self.do_mode(target, msg, nick, send)
            return

        if msgtype == 'join':
            if nick == c.real_nickname:
                send("Joined channel %s" % target, target=self.config['core']['ctrlchan'])
            return

        # ignore empty messages
        if not msg:
            return

        if e.target == self.config['core']['ctrlchan']:
            control.handle_ctrlchan(self, msg, c, send)

        if not self.is_admin(send, nick, False) and nick in self.ignored:
            return

        msg = misc.get_cmdchar(self.config, c, msg, msgtype)
        cmd = msg.split()[0]
        cmdchar = self.config['core']['cmdchar']
        admins = [x.strip() for x in self.config['auth']['admins'].split(',')]

        # handle !s
        cmdlen = len(cmd) + 1
        if cmd.startswith('%ss' % cmdchar):
            match = re.match('%ss(\W)' % cmdchar, cmd)
            if match:
                cmd = cmd.split(match.group(1))[0]
                cmdlen = len(cmd)
        cmdargs = msg[cmdlen:]
        found = False
        if cmd.startswith(cmdchar):
            cmd_name = cmd[len(cmdchar):]
            if command.is_registered(cmd_name):
                found = True
                cmd_obj = command.get_command(cmd_name)
                if cmd_obj.is_limited() and self.abusecheck(send, nick, target, cmd_obj.limit, cmd[len(cmdchar):]):
                    return
                # Duplicate command
                if command.check_command(self.db.get(), nick, msg, target):
                    return
                args = self.do_args(cmd_obj.args, send, nick, target, e.source, c, cmd_name, msgtype)
                cmd_obj.run(send, cmdargs, args, cmd_name, nick, target, self)
        # special commands
        if cmd.startswith(cmdchar):
            if cmd[len(cmdchar):] == 'reload':
                if nick in admins:
                    found = True
                    self.do_reload()
                    send("Aye Aye Capt'n")
            # everything below this point requires admin
            if not found and self.is_admin(send, nick):
                self.do_admin(c, cmd[len(cmdchar):], cmdargs, send, nick, msgtype, target)
Example #7
0
    def handle_msg(self, msgtype, c, e):
        """The Heart and Soul of IrcBot."""

        # actions don't have the nick attr for some reason
        if msgtype == 'action':
            nick = e.source.split('!')[0]
        else:
            nick = e.source.nick

        # modes have separate arguments, everything else just one
        if msgtype == 'mode' or msgtype == 'nick' or msgtype == 'join':
            msg = " ".join(e.arguments)
        else:
            msg = e.arguments[0].strip()

        # Send the response to private messages to the sending nick.
        if msgtype == 'privmsg' or msgtype == 'privnotice':
            target = nick
        else:
            target = e.target

        send = lambda msg, mtype='privmsg', target=target: self.send(target, self.config['core']['nick'], msg, mtype)

        if msgtype == 'privnotice':
            # FIXME: come up with a better way to prevent admin abuse.
            if nick == 'NickServ':
                admin.set_admin(msg, self)
            return

        if msgtype == 'pubnotice':
            return

        if self.config['feature'].getboolean('hooks') and nick not in self.ignored:
                for h in self.hooks:
                    realargs = self.do_args(h.args, send, nick, target, e.source, c, h, msgtype)
                    try:
                        h.run(send, msg, msgtype, self, target, realargs)
                    except InternalError:
                        self.db.rollback()

        if msgtype == 'nick':
            if e.target in self.admins:
                c.send_raw('NS ACC %s' % e.target)
            if identity.handle_nick(self, e):
                for x in misc.get_channels(self.channels, e.target):
                    self.do_kick(send, x, e.target, "identity crisis")
            return

        # must come after set_admin to prevent spam
        self.do_log(target, nick, msg, msgtype)

        if msgtype == 'mode':
            self.do_mode(target, msg, nick, send)
            return

        if msgtype == 'join':
            if nick == c.real_nickname:
                send("Joined channel %s" % target, target=self.config['core']['ctrlchan'])
            return

        # ignore empty messages
        if not msg:
            return

        if e.target == self.config['core']['ctrlchan']:
            control.handle_ctrlchan(self, msg, c, send)

        if not self.is_admin(send, nick, False) and nick in self.ignored:
            return

        msg = misc.get_cmdchar(self.config, c, msg, msgtype)
        cmd = msg.split()[0]
        cmdchar = self.config['core']['cmdchar']
        admins = [x.strip() for x in self.config['auth']['admins'].split(',')]

        # handle !s
        cmdlen = len(cmd) + 1
        if cmd.startswith('%ss' % cmdchar):
            match = re.match('%ss(\W)' % cmdchar, cmd)
            if match:
                cmd = cmd.split(match.group(1))[0]
                cmdlen = len(cmd)
        cmdargs = msg[cmdlen:]
        found = False
        if cmd.startswith(cmdchar):
            cmd_name = cmd[len(cmdchar):]
            if command.is_registered(cmd_name):
                found = True
                cmd_obj = command.get_command(cmd_name)
                if cmd_obj.is_limited() and self.abusecheck(send, nick, target, cmd_obj.limit, cmd[len(cmdchar):]):
                    return
                try:
                    # Duplicate command
                    if command.check_command(self.db.get(), nick, msg, target):
                        return
                    args = self.do_args(cmd_obj.args, send, nick, target, e.source, c, cmd_name, msgtype)
                    cmd_obj.run(send, cmdargs, args, cmd_name, nick, target, self)
                except InternalError:
                    self.db.rollback()
        # special commands
        if cmd.startswith(cmdchar):
            if cmd[len(cmdchar):] == 'reload':
                if nick in admins:
                    found = True
                    self.do_reload()
                    send("Aye Aye Capt'n")
            # everything below this point requires admin
            if not found and self.is_admin(send, nick):
                self.do_admin(c, cmd[len(cmdchar):], cmdargs, send, nick, msgtype, target)
Example #8
0
    def handle_msg(self, msgtype, c, e):
        """The Heart and Soul of IrcBot."""

        nick = e.source.nick

        # modes have separate arguments, everything else just one
        if msgtype == 'mode' or msgtype == 'nick' or msgtype == 'join':
            msg = " ".join(e.arguments)
        else:
            msg = e.arguments[0].strip()

        # ignore empty messages
        if not msg:
            return

        # Send the response to private messages to the sending nick.
        if msgtype == 'privmsg' or msgtype == 'privnotice':
            target = nick
        else:
            target = e.target

        def send(msg, mtype='privmsg', target=target):
            self.send(target, self.connection.real_nickname, msg, mtype)

        if msgtype == 'privnotice':
            # FIXME: come up with a better way to prevent admin abuse.
            if nick == 'NickServ':
                admin.set_admin(msg, self)
            return

        if self.config['feature'].getboolean('hooks') and not self.is_ignored(nick):
            for h in self.hooks.values():
                realargs = self.do_args(h.args, send, nick, target, e.source, h, msgtype)
                h.run(send, msg, msgtype, self, target, realargs)

        if msgtype == 'nick':
            if self.config['feature'].getboolean('nickserv') and e.target in self.admins:
                c.send_raw('NS ACC %s' % e.target)
            if identity.handle_nick(self, e):
                for x in misc.get_channels(self.channels, e.target):
                    self.do_kick(send, x, e.target, "identity crisis")
            return

        # must come after set_admin to prevent spam from all the NickServ ACC responses
        # We log nick changes in bot.py so that they show up for all channels.
        self.do_log(target, nick, msg, msgtype)

        if msgtype == 'mode':
            self.do_mode(target, msg, nick, send)
            return

        if msgtype == 'join':
            if nick == c.real_nickname:
                send("Joined channel %s" % target, target=self.config['core']['ctrlchan'])
            return

        if e.target == self.config['core']['ctrlchan'] and self.is_admin(None, nick):
            control.handle_ctrlchan(self, msg, send)

        if self.is_ignored(nick) and not self.is_admin(None, nick):
            return

        msg = misc.get_cmdchar(self.config, c, msg, msgtype)
        cmd = msg.split()[0]
        cmdchar = self.config['core']['cmdchar']
        admins = [x.strip() for x in self.config['auth']['admins'].split(',')]

        # handle !s
        cmdlen = len(cmd) + 1
        if cmd.startswith('%ss' % cmdchar):
            # escape special regex chars
            raw_cmdchar = '\\' + cmdchar if re.match(r'[\[\].^$*+?]', cmdchar) else cmdchar
            match = re.match(r'%ss(\W)' % raw_cmdchar, cmd)
            if match:
                cmd = cmd.split(match.group(1))[0]
                cmdlen = len(cmd)
        cmdargs = msg[cmdlen:]
        if cmd.startswith(cmdchar) and not msgtype == 'action':
            cmd_name = cmd[len(cmdchar):]
            if command.is_registered(cmd_name):
                cmd_obj = command.get_command(cmd_name)
                if cmd_obj.is_limited() and self.abusecheck(send, nick, target, cmd_obj.limit, cmd[len(cmdchar):]):
                    return
                if cmd_obj.requires_admin() and not self.is_admin(send, nick):
                    send("This command requires admin privileges.")
                    return
                args = self.do_args(cmd_obj.args, send, nick, target, e.source, cmd_name, msgtype)
                cmd_obj.run(send, cmdargs, args, cmd_name, nick, target, self)
            # special commands
            elif cmd[len(cmdchar):] == 'reload':
                if nick in admins:
                    send("Aye Aye Capt'n")