示例#1
0
 def _handleMODE(self, nick, ident, host, params):
     message = None
     if nick in self.bot.users:
         user = self.bot.users[nick]
     else:
         user = IRCUser(nick, ident, host)
     if len(params) > 2:
         modeParams = params[2:]
     else:
         modeParams = []
     if params[0][0] in self.bot.supportHelper.chanTypes:
         if params[0] not in self.bot.channels:
             self.bot.logger.warning(
                 f'Received MODE message for unknown channel {params[0]}.')
             return
         channel = self.bot.channels[params[0]]
         modes = channel.setModes(params[1], modeParams)
         if not modes:
             return
         if len(modes['added']) > 0 or len(modes['removed']) > 0:
             message = IRCMessage('MODE', user, channel, '', self.bot,
                                  modes)
     elif params[0] == self.bot.nick:
         modes = self.bot.setUserModes(params[1])
         if not modes:
             return
         if len(modes['added']) > 0 or len(modes['removed']) > 0:
             message = IRCMessage('MODE', user, None, '', self.bot, modes)
     if message:
         self.handleMessage(message)
示例#2
0
文件: Chain.py 项目: lunik1/DesertBot
    def execute(self, message: IRCMessage):
        # split on unescaped |
        chain = re.split(r'(?<!\\)\|', message.parameters)

        response = None
        extraVars = {}

        for link in chain:
            link = link.strip()
            link = re.sub(r'\\\|', r'|', link)
            if response is not None:
                if hasattr(response, '__iter__'):
                    return IRCResponse(
                        ResponseType.Say,
                        "Chain Error: segment before '{}' returned a list".
                        format(link), message.replyTo)
                # replace $output with output of previous command
                link = link.replace('$output', response.response)
                extraVars.update(response.ExtraVars)
                for var, value in extraVars.items():
                    link = re.sub(r'\$\b{}\b'.format(re.escape(var)),
                                  '{}'.format(value), link)
            else:
                # replace $output with empty string if previous command had no output
                # (or this is the first command in the chain,
                #  but for some reason has $output as a param)
                link = link.replace('$output', '')

            link = link.replace('$sender', message.user.nick)
            if message.channel is not None:
                link = link.replace('$channel', message.channel.name)
            else:
                link = link.replace('$channel', message.user.nick)

            # build a new message out of this 'link' in the chain
            inputMessage = IRCMessage(message.type, message.user,
                                      message.channel,
                                      self.bot.commandChar + link.lstrip(),
                                      self.bot)
            # might be used at some point to tell commands they're being called from Chain
            inputMessage.chained = True

            if inputMessage.command.lower(
            ) in self.bot.moduleHandler.mappedTriggers:
                command = self.bot.moduleHandler.mappedTriggers[
                    inputMessage.command.lower()]
                response = command.execute(inputMessage)
            else:
                return IRCResponse(
                    ResponseType.Say,
                    "{!r} is not a recognized command trigger".format(
                        inputMessage.command), message.replyTo)

        if response.response is not None:
            # limit response length (chains can get pretty large)
            response.response = list(
                string.splitUTF8(response.response.encode('utf-8'), 700))[0]
            response.response = str(response.response, 'utf-8')
        return response
示例#3
0
    def execute(self, message: IRCMessage):
        # split on unescaped |
        chain = re.split(r'(?<!\\)\|', message.parameters)

        response = None
        extraVars = {}

        for link in chain:
            link = link.strip()
            link = re.sub(r'\\\|', r'|', link)
            if response is not None:
                if hasattr(response, '__iter__'):
                    return IRCResponse(ResponseType.Say,
                                       "Chain Error: segment before '{}' returned a list"
                                       .format(link),
                                       message.replyTo)
                # replace $output with output of previous command
                link = link.replace('$output', response.response)
                extraVars.update(response.ExtraVars)
                for var, value in extraVars.items():
                    link = re.sub(r'\$\b{}\b'.format(re.escape(var)), '{}'.format(value), link)
            else:
                # replace $output with empty string if previous command had no output
                # (or this is the first command in the chain,
                #  but for some reason has $output as a param)
                link = link.replace('$output', '')

            link = link.replace('$sender', message.user.nick)
            if message.channel is not None:
                link = link.replace('$channel', message.channel.name)
            else:
                link = link.replace('$channel', message.user.nick)

            # build a new message out of this 'link' in the chain
            inputMessage = IRCMessage(message.type, message.user, message.channel,
                                      self.bot.commandChar + link.lstrip(),
                                      self.bot)
            # might be used at some point to tell commands they're being called from Chain
            inputMessage.chained = True

            if inputMessage.command.lower() in self.bot.moduleHandler.mappedTriggers:
                command = self.bot.moduleHandler.mappedTriggers[inputMessage.command.lower()]
                response = command.execute(inputMessage)
            else:
                return IRCResponse(ResponseType.Say,
                                   "{!r} is not a recognized command trigger"
                                   .format(inputMessage.command),
                                   message.replyTo)

        if response.response is not None:
            # limit response length (chains can get pretty large)
            response.response = list(string.splitUTF8(response.response.encode('utf-8'), 700))[0]
            response.response = str(response.response, 'utf-8')
        return response
示例#4
0
    def _handleINVITE(self, nick, ident, host, params):
        if nick in self.bot.users:
            inviter = self.bot.users[nick]
        else:
            inviter = IRCUser(nick, ident, host)

        invitee = None
        if 'invite-notify' in self.bot.capabilities['finished'] and len(
                params) > 1:
            if params[0] not in self.bot.users:
                invitee = IRCUser(params[0])
            else:
                invitee = self.bot.users[nick]
            chanName = params[1]
        else:
            chanName = params[0]

        if chanName not in self.bot.channels:
            channel = IRCChannel(params[0], self.bot)
        else:
            channel = self.bot.channels[chanName]
        if not invitee or invitee.nick == self.bot.nick:
            self.bot.output.cmdJOIN(chanName)
        message = IRCMessage('INVITE', inviter, channel, '', self.bot,
                             {'invitee': invitee})
        self.handleMessage(message)
示例#5
0
    def _handleKICK(self, nick, ident, host, params):
        if params[0] not in self.bot.channels:
            self.bot.logger.warning(
                f'Received KICK message for unknown channel {params[0]}.')
            return
        channel = self.bot.channels[params[0]]
        if params[1] not in channel.users:
            self.bot.logger.warning(
                f'Received KICK message for unknown user {nick} in channel {params[0]}.'
            )
            return
        if nick not in self.bot.users:
            # Technically opers could KICK a user despite not being in the channel themselves
            kicker = IRCUser(nick, ident, host)
        else:
            kicker = self.bot.users[nick]
        kicked = self.bot.users[params[1]]
        reason = ''
        if len(params) > 2:
            reason = params[2]

        message = IRCMessage('KICK', kicker, channel, reason, self.bot,
                             {'kicked': kicked})
        self.handleMessage(message)

        # We need to run the action before we actually get rid of the user
        if kicked.nick == self.bot.nick:
            del self.bot.channels[params[0]]
        else:
            del channel.users[kicked.nick]
            del channel.ranks[kicked.nick]
示例#6
0
文件: Alias.py 项目: lunik1/DesertBot
    def _aliasedMessage(self, message):
        if message.command.lower() not in self.aliases:
            return

        alias = self.aliases[message.command.lower()]
        newMsg = "{0}{1}".format(self.bot.commandChar, alias)

        newMsg = newMsg.replace("$sender", message.user.nick)
        if message.channel is not None:
            newMsg = newMsg.replace("$channel", message.channel.name)
        else:
            newMsg = newMsg.replace("$channel", message.user.nick)

        paramList = [
            self._mangleReplacementPoints(param)
            for param in message.parameterList
        ]

        # if the alias contains numbered param replacement points, replace them
        if re.search(r'\$[0-9]+', newMsg):
            newMsg = newMsg.replace("$0", " ".join(paramList))
            for i, param in enumerate(paramList):
                if newMsg.find("${}+".format(i + 1)) != -1:
                    newMsg = newMsg.replace("${}+".format(i + 1),
                                            " ".join(paramList[i:]))
                else:
                    newMsg = newMsg.replace("${}".format(i + 1), param)
        # if there are no numbered replacement points, append the full parameter list instead
        else:
            newMsg += " {}".format(" ".join(paramList))

        newMsg = self._unmangleReplacementPoints(newMsg)

        return IRCMessage(message.type, message.user, message.channel, newMsg,
                          self.bot)
示例#7
0
 def _handleTriggerCommand(self, message: IRCMessage, triggerCommand: str) -> IRCResponse:
     self.logger.debug(f"{triggerCommand} executing from a trigger")
     newMessage = IRCMessage(message.type, message.user, message.channel, f"{self.bot.commandChar}{triggerCommand}", self.bot)
     newCommand = newMessage.command.lower()
     self.logger.debug(f"Command appears to be: {newCommand}")
     if newCommand in self.bot.moduleHandler.mappedTriggers:
         return self.bot.moduleHandler.mappedTriggers[newCommand].execute(newMessage)
示例#8
0
 def _handleNumeric324(self, prefix, params):
     # 324: RPL_CHANNELMODEIS
     channel = self.bot.channels[params[1]]
     modeParams = params[3].split() if len(params) > 3 else []
     modes = channel.setModes(params[2], modeParams)
     if modes:
         message = IRCMessage('324', IRCUser(prefix), None, '', self.bot,
                              modes)
         self.handleMessage(message)
示例#9
0
 def _handleNumeric001(self, prefix, params):
     # 001: RPL_WELCOME
     self.bot.loggedIn = True
     self.bot.factory.connectionAttempts = 0
     message = IRCMessage('001', IRCUser(prefix), None, '', self.bot)
     self.handleMessage(message)
     channels = self.bot.config.getWithDefault('channels', {})
     for channel, key in channels.items():
         self.bot.output.cmdJOIN(channel, key if key else '')
示例#10
0
    def execute(self, message: IRCMessage):
        if len(message.parameterList) < 2:
            return IRCResponse(ResponseType.Say, self.help(None),
                               message.replyTo)

        command = message.parameterList[1].lower()
        delay = timeparse(message.parameterList[0])
        if not delay:
            delay = 0

        delayDelta = datetime.timedelta(seconds=delay)
        delayString = string.deltaTimeToString(delayDelta, 's')
        params = message.parameterList[2:]
        commandString = '{}{} {}'.format(self.bot.commandChar, command,
                                         ' '.join(params))
        commandString = commandString.replace('$delayString', delayString)
        commandString = commandString.replace('$delay', str(delay))

        newMessage = IRCMessage(message.type, message.user, message.channel,
                                commandString, self.bot)

        moduleHandler = self.bot.moduleHandler
        if command in moduleHandler.mappedTriggers:
            module = moduleHandler.mappedTriggers[command].execute
            d = task.deferLater(reactor, delay, module, newMessage)
            d.addCallback(self._activate)
            d.addErrback(self._deferredError)
            return IRCResponse(
                ResponseType.Say,
                "OK, I'll execute that in {}".format(delayString),
                message.replyTo, {
                    'delay': delay,
                    'delayString': delayString
                })
        else:
            if 'Alias' not in moduleHandler.commands:
                return IRCResponse(
                    ResponseType.Say,
                    "'{}' is not a recognized command".format(command),
                    message.replyTo)

            if command not in moduleHandler.commands['Alias'].aliases:
                return IRCResponse(
                    ResponseType.Say,
                    "'{}' is not a recognized command or alias".format(
                        command), message.replyTo)

            d = task.deferLater(reactor, delay,
                                moduleHandler.commands['Alias'].execute,
                                newMessage)
            d.addCallback(self._activate)
            d.addErrback(self._deferredError)
            return IRCResponse(
                ResponseType.Say,
                "OK, I'll execute that in {}".format(delayString),
                message.replyTo)
示例#11
0
    def activate(self):
        commandStr = '{}{} {}'.format(self.bot.commandChar, self.command,
                                      ' '.join(self.params))
        self.logger.info("Activated {!r}".format(commandStr))
        message = IRCMessage('PRIVMSG', IRCUser(self.user),
                             IRCChannel(self.channel, self.bot), commandStr,
                             self.bot)

        trigger = self.bot.moduleHandler.mappedTriggers[self.command].execute

        return trigger(message)
示例#12
0
 def _handleNOTICE(self, nick, ident, host, params):
     user = None
     if params[0][0] in self.bot.supportHelper.chanTypes:
         if params[0] in self.bot.channels:
             source = self.bot.channels[params[0]]
         else:
             # We got a notice for an unknown channel. Create a temporary IRCChannel object for it.
             source = IRCChannel(params[0], self.bot)
         if nick in self.bot.users:
             user = self.bot.users[nick]
         else:
             user = IRCUser(nick, ident, host)
     elif nick in self.bot.users:
         source = self.bot.users[nick]
     else:
         # We got a notice from an unknown user. Create a temporary IRCUser object for them.
         source = IRCUser(nick, ident, host)
     if isinstance(source, IRCChannel):
         message = IRCMessage('NOTICE', user, source, params[1], self.bot)
     else:
         message = IRCMessage('NOTICE', source, None, params[1], self.bot)
     self.handleMessage(message)
示例#13
0
 def _handlePRIVMSG(self, nick, ident, host, params):
     user = None
     if params[0][0] in self.bot.supportHelper.chanTypes:
         if params[0] in self.bot.channels:
             source = self.bot.channels[params[0]]
         else:
             # We got a message for an unknown channel. Create a temporary IRCChannel object for it.
             source = IRCChannel(params[0], self.bot)
         if nick in self.bot.users:
             user = self.bot.users[nick]
         else:
             user = IRCUser(nick, ident, host)
     elif nick in self.bot.users:
         source = self.bot.users[nick]
         user = source
     else:
         # We got a message from an unknown user. Create a temporary IRCUser object for them.
         source = IRCUser(nick, ident, host)
     if len(params) == 1:
         self.bot.logger.warning('Received a blank PRIVMSG')
         params.append('')
     if params[1] and params[1][0] == '\x01':
         msgType = 'CTCP'
         msgStr = params[1][1:len(params[1]) - 1]
         if msgStr.upper().startswith('ACTION'):
             msgType = 'ACTION'
             msgStr = msgStr[7:]
         if isinstance(source, IRCChannel):
             message = IRCMessage(msgType, user, source, msgStr, self.bot)
         else:
             message = IRCMessage(msgType, source, None, msgStr, self.bot)
     elif isinstance(source, IRCChannel):
         message = IRCMessage('PRIVMSG', user, source, params[1], self.bot)
     else:
         message = IRCMessage('PRIVMSG', source, None, params[1], self.bot)
     self.handleMessage(message)
示例#14
0
 def _handleTOPIC(self, nick, ident, host, params):
     if params[0] not in self.bot.channels:
         self.bot.logger.warning(
             f'Received TOPIC message for unknown channel {params[0]}.')
         return
     channel = self.bot.channels[params[0]]
     if nick not in self.bot.users:
         # A user that's not in the channel can change the topic so let's make a temporary user.
         user = IRCUser(nick, ident, host)
     else:
         user = self.bot.users[nick]
     oldTopic = channel.topic
     channel.topic = params[1]
     channel.topicSetter = user.fullUserPrefix()
     channel.topicTimestamp = timestamp(now())
     message = IRCMessage('TOPIC', user, channel, params[1], self.bot,
                          {'oldtopic': oldTopic})
     self.handleMessage(message)
示例#15
0
 def _handleQUIT(self, nick, ident, host, params):
     if nick not in self.bot.users:
         self.bot.logger.warning(
             f'Received a QUIT message for unknown user {nick}.')
         return
     reason = ''
     if len(params) > 0:
         reason = params[0]
     user = self.bot.users[nick]
     quitChannels = [
         chan for _, chan in self.bot.channels.items() if nick in chan.users
     ]
     message = IRCMessage('QUIT', user, None, reason, self.bot,
                          {'quitChannels': quitChannels})
     self.handleMessage(message)
     for channel in self.bot.channels.values():
         if nick in channel.users:
             del channel.users[nick]
             del channel.ranks[nick]
示例#16
0
 def _handleNICK(self, nick, ident, host, params):
     if nick not in self.bot.users:
         self.bot.logger.warning(
             f'Received NICK message for unknown user {nick}.')
         return
     user = self.bot.users[nick]
     newNick = params[0]
     user.nick = newNick
     self.bot.users[newNick] = user
     del self.bot.users[nick]
     for channel in self.bot.channels.values():
         if nick in channel.users:
             channel.users[newNick] = user
             channel.ranks[newNick] = channel.ranks[nick]
             del channel.users[nick]
             del channel.ranks[nick]
     if nick == self.bot.nick:
         self.bot.nick = newNick
     message = IRCMessage('NICK', user, None, newNick, self.bot,
                          {'oldnick': nick})
     self.handleMessage(message)
示例#17
0
    def _handleJOIN(self, nick, ident, host, params):
        if nick not in self.bot.users:
            user = IRCUser(nick, ident, host)
            if 'extended-join' in self.bot.capabilities['finished'] and len(
                    params) > 1:
                if params[1] != '*':
                    user.account = params[1]
                user.gecos = params[2]
            self.bot.users[nick] = user
        else:
            user = self.bot.users[nick]

        if params[0] not in self.bot.channels:
            channel = IRCChannel(params[0], self.bot)
            self.bot.output.cmdWHO(params[0])
            self.bot.output.cmdMODE(params[0])
            self.bot.channels[params[0]] = channel
        else:
            channel = self.bot.channels[params[0]]
        channel.users[nick] = user
        channel.ranks[nick] = ''
        message = IRCMessage('JOIN', user, channel, '', self.bot)
        self.handleMessage(message)
示例#18
0
 def _handlePART(self, nick, ident, host, params):
     if params[0] not in self.bot.channels:
         self.bot.logger.warning(
             f'Received PART message for unknown channel {params[0]}.')
         return
     channel = self.bot.channels[params[0]]
     if nick not in channel.users:
         self.bot.logger.warning(
             f'Received PART message for unknown user {nick} in channel {params[0]}.'
         )
         return
     reason = ''
     if len(params) > 1:
         reason = params[1]
     user = self.bot.users[nick]
     # We need to run the action before we actually get rid of the user
     message = IRCMessage('PART', user, channel, reason, self.bot)
     self.handleMessage(message)
     if nick == self.bot.nick:
         del self.bot.channels[params[0]]
     else:
         del channel.users[nick]
         del channel.ranks[nick]
示例#19
0
    def execute(self, message: IRCMessage):
        subString = self._mangleEscapes(message.parameters)

        try:
            segments = list(self._parseSubcommandTree(subString))
        except UnbalancedBracesException as e:
            red = colour(A.bold[A.fg.lightRed['']])
            normal = colour(A.normal[''])
            error = (subString[:e.column] + red + subString[e.column] +
                     normal + subString[e.column + 1:])
            error = self._unmangleEscapes(error, False)
            return [
                IRCResponse(ResponseType.Say,
                            "Sub Error: {}".format(e.message),
                            message.replyTo),
                IRCResponse(ResponseType.Say, error, message.replyTo)
            ]

        prevLevel = -1
        responseStack = []
        extraVars = {}
        metadata = {}

        for segment in segments:
            (level, command, start, end) = segment

            # We've finished executing subcommands at the previous depth,
            # so replace subcommands with their output at the current depth
            if level < prevLevel:
                command = self._substituteResponses(command, responseStack,
                                                    level, extraVars, start)

            # Replace any extraVars in the command
            for var, value in extraVars.items():
                command = re.sub(r'\$\b{}\b'.format(re.escape(var)),
                                 '{}'.format(value), command)

            # Build a new message out of this segment
            inputMessage = IRCMessage(message.type,
                                      message.user,
                                      message.channel,
                                      self.bot.commandChar + command.lstrip(),
                                      self.bot,
                                      metadata=metadata)

            # Execute the constructed message
            if inputMessage.command.lower(
            ) in self.bot.moduleHandler.mappedTriggers:
                module = self.bot.moduleHandler.mappedTriggers[
                    inputMessage.command.lower()]
                response = module.execute(inputMessage)
                """@type : IRCResponse"""
            else:
                return IRCResponse(
                    ResponseType.Say,
                    "'{}' is not a recognized command trigger".format(
                        inputMessage.command), message.replyTo)

            # Push the response onto the stack
            responseStack.append((level, response.response, start, end))
            # Update the extraVars dict
            extraVars.update(response.ExtraVars)
            metadata = self._recursiveMerge(metadata, response.Metadata)

            prevLevel = level

        responseString = self._substituteResponses(subString, responseStack,
                                                   -1, extraVars, -1)
        responseString = self._unmangleEscapes(responseString)
        return IRCResponse(ResponseType.Say,
                           responseString,
                           message.replyTo,
                           extraVars=extraVars,
                           metadata=metadata)