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)
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()
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')
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)
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)
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)
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")