Beispiel #1
0
    def lineReceived(self, line):
        line = irc_decode(irc.lowDequote(line))

        try:
            prefix, command, params = irc.parsemsg(line)
            self.handleCommand(command, prefix, params)
        except irc.IRCBadMessage:
            # emit and ignore
            traceback.print_exc()
            return

        if self.__botIsEnable:
            database.client.write(self.__nickname,
                                  command + " " + (' '.join(params)))

        if command == "001":
            self.__nickname = params[0]

            if self.__perform is not None:
                for x in self.__perform:
                    self.write(x)
                self.__perform = None
        elif command == "NICK":
            nick = prefix.split("!", 1)[0]
            if nick == self.__nickname:
                self.__nickname = params[0]
Beispiel #2
0
    def lineReceived(self, line):
        """Called for every line received from the server."""
        # The IRC spec does not specify a message encoding, meaning that some
        # messages may fail to decode into a UTF-8 string. While we must be
        # aware of the issue and choose to replace "invalid" characters (which
        # are technically valid per the IRC RFC, hence us warning about this
        # behavior), we must also ensure that the Twisted IRCClient's
        # implementation of lineReceived does not receive these characters, as
        # it will not replace them.
        try:
            line = line.decode('utf-8')
        except UnicodeDecodeError:
            self.logger.warning(
                "Stripping non-UTF-8 data from received line: {}".format(line))
            line = line.decode('utf-8', 'replace')

        # Log raw output
        self.irc_logger.info(line)

        # Log if the command received is in the error range
        _, command, _ = irc.parsemsg(line)
        if command.isnumeric() and 400 <= int(command) <= 599:
            self.logger.warning(
                "Received an error from the server: {}".format(line))

        self.event_manager.fire("irc.raw", command, line)

        # Send IRCClient the version of the line that has had non-UTF-8
        # characters replaced.
        #
        # Bug: https://twistedmatrix.com/trac/ticket/9443
        super().lineReceived(line.encode('utf-8'))
Beispiel #3
0
 def parse(self, connection, outgoing, raw, **kwargs):
     """Parse a raw IRC message string and return a corresponding
     `.Message` object.  Any keyword arguments override field values
     returned by the parser."""
     try:
         prefix, command, params = parsemsg(raw)
     except IndexError:
         parsed_kwargs = {'action': 'unknown'}
     else:
         parsed_kwargs = {'actor': Hostmask.from_string(prefix)}
         if command in self.functions:
             try:
                 parsed_kwargs['action'] = command.lower()
                 parsed_kwargs.update(
                     self.functions[command](command, params))
             except IndexError:
                 del parsed_kwargs['action']
         if 'action' not in parsed_kwargs:
             parsed_kwargs['action'] = 'unknown'
             parsed_kwargs['subaction'] = command
             splits = 2 if raw.startswith(':') else 1
             params = raw.split(None, splits)
             if len(params) > splits:
                 parsed_kwargs['content'] = params[splits]
             else:
                 parsed_kwargs['content'] = ''
     parsed_kwargs.update(kwargs)
     return Message(connection, outgoing, raw=raw, **parsed_kwargs)
Beispiel #4
0
  def lineReceived(self, line):
    line = irc_decode(irc.lowDequote(line))
    
    try:
      prefix, command, params = irc.parsemsg(line)
      self.handleCommand(command, prefix, params)
    except irc.IRCBadMessage:
      # emit and ignore
      traceback.print_exc()
      return

    if self.__botIsEnable:  
      database.client.write( self.__nickname, command + " "+(' '.join(params)) )

    if command == "001":
      self.__nickname = params[0]
      
      if self.__perform is not None:
        for x in self.__perform:
          self.write(x)
        self.__perform = None
    elif command == "NICK":
      nick = prefix.split("!", 1)[0]
      if nick == self.__nickname:
        self.__nickname = params[0]
Beispiel #5
0
 def response(self):
     """
     Grabs our responses and then clears the transport
     """
     response = self.ircUser.transport.value()
     self.ircUser.transport.clear()
     if bytes != str and isinstance(response, bytes):
         response = response.decode("utf-8")
     response = response.splitlines()
     return [irc.parsemsg(r) for r in response]
Beispiel #6
0
    def lineReceived(self, line):
        irc.IRCClient.lineReceived(self, line)

        print line

        prefix, command, params = irc.parsemsg(line)

        if command == "ERROR":
            if params and params[0].find("too fast") != -1:
                print "Client trying to reconnect too fast."
Beispiel #7
0
 def lineReceived(self, line):
     line = irc.lowDequote(line).decode(self.config['charset'], 'replace')
     try:
         prefix, command, params = irc.parsemsg(line)
         if command in irc.numeric_to_symbolic:
             parsedcmd = irc.numeric_to_symbolic[command]
         else:
             parsedcmd = command
         self.handleCommand(parsedcmd, prefix, params)
         if self._registered:
             self.event_raw(command, prefix, params)
     except irc.IRCBadMessage:
         self.badMessage(line, *sys.exc_info())
Beispiel #8
0
 def lineReceived(self, line):
     """
     Override IRCClient.lineReceived() to properly decode bytes to unicode and ignore errors.
     """
     if isinstance(line, bytes):
         line = line.decode("utf-8", errors="ignore")
     line = lowDequote(line)
     try:
         prefix, command, params = parsemsg(line)
         if command in numeric_to_symbolic:
             command = numeric_to_symbolic[command]
         self.handleCommand(command, prefix, params)
     except IRCBadMessage:
         self.badMessage(line, *sys.exc_info())
Beispiel #9
0
 def lineReceived(self, line): # use instead of query
     line = irc.lowDequote(line)
     try:
         prefix, command, params = irc.parsemsg(line)
         if irc.numeric_to_symbolic.has_key(command):
             command = irc.numeric_to_symbolic[command]
         self.handleCommand(command, prefix, params)
     except irc.IRCBadMessage:
         self.badMessage(line, *sys.exc_info())
     try:
         if command == "RPL_NAMREPLY":
             names = params[3].split()
             for name in names:
                 if name.startswith("@"):
                     self.ops.append(name[1:])
     except:
         self.logger.error(traceback.format_exc())
Beispiel #10
0
 def lineReceived(self, line):
     line_str = line.decode('utf-8')
     # self.log.debug(line_str)
     if line_str.startswith('@'):
         tags = line_str[1:].split(':')[0].split(' ')[0].split(';')
         tags = dict(t.split('=') for t in tags)
         line_str = ':' + line_str.split(' :', 1)[1]
         # noinspection PyTypeChecker
         prefix, cmd, args = irc.parsemsg(line_str)
         if cmd == "PRIVMSG":
             self.privmsg(prefix, args[0], args[1], tags)
         elif cmd == "WHISPER":
             self.privmsg(prefix, args[0], args[1], tags)
         elif cmd == "USERSTATE":
             self.log.info('USERSTATE: %s' % str(tags))
         elif cmd == "ROOMSTATE":
             self.log.info('ROOMSTATE: %s' % str(tags))
         elif cmd == "USERNOTICE":
             if len(args) == 2:
                 self.log.info(
                     'User %s has resubscribed to the channel!: %s' %
                     (tags['login'], args[1]))
             else:
                 self.log.info('User %s has resubscribed to the channel!' %
                               tags['login'])
         elif cmd == "HOSTTARGET":
             if args[1].split(' ')[0] == "-":
                 self.log.info('Exited host mode in %s.' % args[0])
             else:
                 self.log.info('%s now hosting %s with %s viewers.' %
                               (args[0], args[1], args[2]))
         elif cmd == "CLEARCHAT":
             if len(args) == 1:
                 self.log.info('Chat has been cleared in %s!' % args[0])
             elif len(args) == 2:
                 self.log.info('User %s has been banned from the chat.' %
                               args[1])
         elif cmd == "RECONNECT":
             # TODO: Implement logic to reconnect and rejoin eventually
             self.log.warning(
                 'Received reconnect notice from the Twitch server!')
         elif cmd == "NOTICE":
             # TODO: Finish implementing this for logging purposes
             pass
     else:
         irc.IRCClient.lineReceived(self, line)
Beispiel #11
0
    def lineReceived(self, line):
        global total_channels, joined_channels, number_of_total_channels, total_channels_flag
        if bytes != str and isinstance(line, bytes):
            # decode bytes from transport to unicode
            #line = line.decode('utf-8', 'backslashreplace')
            line = line.decode('utf-8', 'ignore')
        line = irc.lowDequote(line)

        try:
            prefix, command, params = irc.parsemsg(line)
            all_params = ''.join([p for p in params]).lower()
            # too many channels
            # if '405' in command:
            #     if 'You have joined too many channels' in params[2]:
            #        print('Total channels before restrict: ' + str(joined_channels))

            ### skip not interesting messages
            # to_skip = set(['372', '332', '353', '322', 'PRIVMSG', 'QUIT'])
            # to_skip = set(['353', '322', 'PRIVMSG'])
            to_skip = set([''])
            if (command not in to_skip) or (FULL_LOG == 1):
                print('prefix: {}, command: {}, params: {}'.format(prefix, command, params))

            ### SASL auth if requiered
            if 'CAP' in command:
                print('CAP')
                if 'ack' in all_params:
                    self.sendLine('AUTHENTICATE PLAIN')
                    print('AUTHENTICATE PLAIN')
                if 'ls' in all_params:
                    print('ls')
                    if 'sasl' in all_params:
                        print('sasl')
                        self.sendLine('CAP REQ :sasl')
                        print('CAP REQ :sasl')
            if 'AUTHENTICATE' in command:
                if '+' in params[0]:
                    self.auth_with_SASL()
            if '903' in command:
                self.identified = True
                return

            ### ERROR
            if 'error' in command.lower():
                if 'too fast' in params[0]:
                    self.logger.log('[{}: An error occured: {}]'.format(
                        self.nickname,
                        params[0]
                    ))
                    time.sleep(10)
            if '4' in str(command)[0]:
                self.logger.log('[{}: An error occured: {}]'.format(
                    self.nickname,
                    ' '.join([s for s in params])
                ))

            ### 353: users in channel
            # if '353' in command:
            #     if self.nickname in params[3]:
            #         self.joined(params[2])
            #         return

            ### 433: Nickname is already in use
            if '433' in command:
                self.setNick(get_random_nick())

            ### irc.cyberarmy.net need to pause 60 sec to request /LIST
            if 'you cannot list within the first' in ''.join([p for p in params]).lower():
                time.sleep(60)
                self.sendLine('LIST')

            ### total joined channels
            if '319' in command:
                joined_channels += params[2]
            if '318' in command:
                self.logger.log('[{}: joined channels at this time: {} of all {}]'.format(
                    self.nickname,
                    len(joined_channels.split(' '))-1,
                    number_of_total_channels
                ))

            ### signed on server
            signed_commands = ['903', '376', '422']
            if command in signed_commands:
                if not self.bot_signed:
                    self.signedOn()
                return

            #### total channels on server
            if '322' in command:  # params[1] - channel name, params[2] - number of users
                # print(command)
                try:
                    if int(params[-2]) >= MINIMUM_USERS:
                        if MAXIMUM_USERS:
                            if int(params[-2]) <= MAXIMUM_USERS:
                                total_channels.append(params[1])
                        else:
                            total_channels.append(params[1])
                except:
                    print ('Channel %s have unformatted number of users' % params[1])
            # if 'End of /LIST' in params:
            if '323' in command:
                # total_channels = self.channels.copy()
                number_of_total_channels = len(total_channels)
                total_channels_flag = True
                self.logger.log('[Summary channels to join: {}]'.format(len(total_channels)))

            if command in irc.numeric_to_symbolic:
                command = irc.numeric_to_symbolic[command]
            else:
                self.handleCommand(command, prefix, params)

            ### Identifiend
            identified_list = ['You are now logged', 'You are now identified', 'There are already', 'No such nick']
            if (len(params) > 0) and (self.nickname == params[0]):
                for i in identified_list:
                    if i.lower() in all_params:
                        ### Server may have limit for nick identified in one account
                        ### and we need to try to get all others channels without make identified
                        self.identified = True

            ### joining channels
            if self.write_time and len(self.channels) > 0:
                delta = datetime.now() - self.write_time
                if int(delta.total_seconds()) > 5:
                    self.join_channels()


        except irc.IRCBadMessage:
            print(line)
            self.badMessage(line, *sys.exc_info())
Beispiel #12
0
    def lineReceived(self, line):
        line = irc_decode(irc.lowDequote(line))

        try:
            prefix, command, params = irc.parsemsg(line)
            self.handleCommand(command, prefix, params)
        except irc.IRCBadMessage:
            # emit and ignore
            traceback.print_exc()
            return

        if command == "CAP":
            if (self.registered):
                return

            # We're performing CAP negotiation.
            # We're receiving the list. Wait until its complete, then request what
            # we want.
            if (params[1] == "LS"):
                if (self.saslauth):
                    return
                if (params[2] == "*"):
                    self.cap.extend(params[3].split(" "))
                else:
                    self.cap.extend(params[2].split(" "))
                    reqlist = []
                    if ("multi-prefix" in self.cap):
                        reqlist.append("multi-prefix")
                    if ("sasl" in self.cap):
                        if (self.authUser and self.authSecret):
                            self.saslauth = True
                            reqlist.append("sasl")
                    if (reqlist):
                        self.write("CAP REQ :" + ' '.join(reqlist))
                        self.cap = reqlist
                    else:
                        self.write("CAP END")

            # We're receiving acknowledgement of requested features. Handle it.
            # Once all acknowledgements are received, end CAP is SASL is not
            # underway.
            if "ACK" in params:
                if "sasl" in params[-1].split(" "):
                    if (self.authUser and self.authSecret):
                        self.write("AUTHENTICATE " +
                                   config.atheme["sasl_type"])
                        self.saslauth = True
                if (not self.saslauth):
                    self.write("CAP END")

            # We're receiving negative acknowledgement; a feature upgrade was denied.
            # Once all acknowledgements are received, end CAP is SASL is not
            # underway.
            if (params[1] == "NACK"):
                for item in params[2].split(" "):
                    self.cap.remove(item)
                if (not self.saslauth):
                    self.write("CAP END")

        # Handle SASL authentication requests.
        if (command == "AUTHENTICATE"):
            if (not self.saslauth):
                return

            # We're performing SASL auth. Send them our authcookie.
            authtext = base64.b64encode('\0'.join(
                [self.authUser, self.authUser, self.authSecret]))
            while (len(authtext) >= 400):
                self.write("AUTHENTICATE " + authtext[0:400])
                authtext = authtext[400:]
            if (len(authtext) != 0):
                self.write("AUTHENTICATE " + authtext)
            else:
                self.write("AUTHENTICATE +")

        # Handle SASL result messages.
        # End CAP after one of these, unless an acknowledgement message is still
        # waiting.
        if (command in ["903", "904", "905", "906", "907"]):
            if (self.saslauth):
                self.saslauth = False
                if (not self.saslauth):
                    self.write("CAP END")

        if command == "001":
            self.registered = True
            self.__nickname = params[0]

            if self.__perform is not None:
                for x in self.__perform:
                    self.write(x)
                self.__perform = None
        elif command == "NICK":
            nick = prefix.split("!", 1)[0]
            if nick == self.__nickname:
                self.__nickname = params[0]
Beispiel #13
0
 def init_linestr(self, linestr):
     self.linestr = linestr
     # parse the line into a normalized form
     self.prefix, self.cmd, self.args = irc.parsemsg(linestr)
     if self.prefix == '': self.prefix = None
     self.cmd = self.cmd.upper()
Beispiel #14
0
  def lineReceived(self, line):
    line = irc_decode(irc.lowDequote(line))
    
    try:
      prefix, command, params = irc.parsemsg(line)
      self.handleCommand(command, prefix, params)
    except irc.IRCBadMessage:
      # emit and ignore
      traceback.print_exc()
      return

    if command == "CAP":
      if (self.registered):
        return

      # We're performing CAP negotiation.
      # We're receiving the list. Wait until its complete, then request what
      # we want.
      if (params[1] == "LS"):
        if (self.saslauth):
          return
        if (params[2] == "*"):
          self.cap.extend(params[3].split(" "))
        else:
          self.cap.extend(params[2].split(" "))
          reqlist = []
          if ("multi-prefix" in self.cap):
            reqlist.append("multi-prefix")
          if ("sasl" in self.cap):
            if (self.authUser and self.authSecret):
              self.saslauth = True
              reqlist.append("sasl")
          if (reqlist):
            self.write("CAP REQ :" + ' '.join(reqlist))
            self.cap = reqlist
          else:
            self.write("CAP END")
      
      # We're receiving acknowledgement of requested features. Handle it.
      # Once all acknowledgements are received, end CAP is SASL is not
      # underway.
      if "ACK" in params:
        if "sasl" in params[-1].split(" "):
          if (self.authUser and self.authSecret):
            self.write("AUTHENTICATE "+config.atheme["sasl_type"])
            self.saslauth = True
        if (not self.saslauth):
          self.write("CAP END")

      # We're receiving negative acknowledgement; a feature upgrade was denied.
      # Once all acknowledgements are received, end CAP is SASL is not
      # underway.
      if (params[1] == "NAK"):
        for item in params[2].split(" "):
          self.cap.remove(item)
        if (not self.saslauth):
          self.write("CAP END")

    
    # Handle SASL authentication requests.
    if (command == "AUTHENTICATE"):
      if (not self.saslauth):
        return

      # We're performing SASL auth. Send them our authcookie.
      authtext = base64.b64encode('\0'.join([self.authUser, self.authUser, self.authSecret]))
      while (len(authtext) >= 400):
        self.write("AUTHENTICATE " + authtext[0:400])
        authtext = authtext[400:]
      if (len(authtext) != 0):
        self.write("AUTHENTICATE " + authtext)
      else:
        self.write("AUTHENTICATE +")

    # Handle SASL result messages.
    # End CAP after one of these, unless an acknowledgement message is still
    # waiting.
    if (command in ["903", "904", "905","906","907"]):
      if (self.saslauth):
        self.saslauth = False
        if (not self.saslauth):
          self.write("CAP END")
        
    if command == "001":
      f = self.factory.ircinit
      self.write("NS IDENTIFY %s %s" % (f["nick"], f["pass"]))
      self.registered = True
      self.__nickname = params[0]
      
      if self.__perform is not None:
        for x in self.__perform:
          self.write(x)
        self.__perform = None
    elif command == "NICK":
      nick = prefix.split("!", 1)[0]
      if nick == self.__nickname:
        self.__nickname = params[0]