From 1e18a18a3cd3895ac469d9e5db825b574d24ee6f Mon Sep 17 00:00:00 2001 From: Josh K Date: Fri, 17 May 2019 19:13:06 -0400 Subject: [PATCH] Fixed parsing messages from users with ipv6 hosts. Bot disconnects from server on ERROR messages. --- bot.py | 4 ++-- protocol.py | 30 ++++++++++++++++++++++-------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/bot.py b/bot.py index 61efe7e..de65323 100644 --- a/bot.py +++ b/bot.py @@ -75,7 +75,7 @@ def parser(): """ message parser decorator. decorated function gets passed con, dst, nick, msg on each privmsg - by default, bot's own messages are caught by parsers too + even bot's own messages are sent to parsers """ def __deco__( func ): mod = add_module( func.__module__ ) @@ -165,7 +165,7 @@ def _on_priv_message( con, dst, nick, msg ): parms, {'con':con,'dst':dst,'nick':nick} ) ) break - # callback registered parsers, self messages too by default + # callback registered parsers, for self messages too #if nick != bcfg['user']['nick']: for v in _MOD_MAP.values(): for p in v['parsers']: diff --git a/protocol.py b/protocol.py index 5c0d28d..d72d143 100644 --- a/protocol.py +++ b/protocol.py @@ -79,6 +79,11 @@ class IrcProtocol( asyncio.Protocol ): self._dat = self._dat[self._dat.index( b'\r\n' ) + 2:] words = raw_msg.split() + if 'ERROR' in words[0]: self.log( raw_msg ) + # closing error (too many users?!) + if 'Closing' in words[1]: + self._stop = True + if words[0] == 'PING': self.send( 'PONG ' + words[1] ) # register success, join initial channels if words[1] == '001': @@ -92,7 +97,7 @@ class IrcProtocol( asyncio.Protocol ): dst = words[2] raw_user = words[0] nick = raw_user[1 : words[0].find( '!' )] - msg = raw_msg[raw_msg.find( ':' , 1 ) + 1 :] + msg = raw_msg[raw_msg.find( ':' , len( words[0] ) ) + 1 :] for cb in self._cb['message']: cb( self, dst, nick, msg ) # on names elif words[1] == '353': @@ -106,16 +111,23 @@ class IrcProtocol( asyncio.Protocol ): self.join_name( n, names_chan ) # update names (add callbacks?) elif 'JOIN' in words[1]: + self.log( '::JOIN:: {}'.format( raw_msg ) ) nick = words[0][1:words[0].find('!')] + jchan = words[2] + if jchan[0] == ':': jchan = jchan[1:] if nick == self.cfg['usr']['nick']: - self.log( '::JOIN:: {} has joined {}.'.format( nick, words[2][1:] ) ) - self.join_name( nick, words[2][1:] ) + self.log( '::JOIN:: {} has joined {}.'.format( nick, jchan ) ) + self.join_name( nick, jchan ) elif 'PART' in words[1]: + self.log( '::PART:: {}'.format( raw_msg ) ) nick = words[0][1:words[0].find('!')] + pchan = words[2] + if pchan[0] == ':': pchan = pchan[1:] if nick == self.cfg['usr']['nick']: - self.log( '::PART:: {} has left {}.'.format( nick, words[2] ) ) - self.part_name( nick, words[2] ) + self.log( '::PART:: {} has left {}.'.format( nick, pchan ) ) + self.part_name( nick, pchan ) elif 'QUIT' in words[1]: + self.log( '::QUIT:: {}'.format( raw_msg ) ) nick = words[0][1:words[0].find('!')] if nick == self.cfg['usr']['nick']: self.log( '::QUIT:: {} has quit the server.'.format( nick ) ) @@ -128,9 +140,11 @@ class IrcProtocol( asyncio.Protocol ): if newnick[0] == ':': newnick = newnick[1:] self.change_name( nick, newnick ) elif 'KICK' in words[1]: + kchan = words[2] + if kchan[0] == ':': kchan = kchan[1:] if words[3] == self.cfg['usr']['nick']: - self.log( '::KICK:: {} has been kicked from {}.'.format( words[3], words[2] ) ) - self.part_name( words[3], words[2] ) + self.log( '::KICK:: {} has been kicked from {}.'.format( words[3], kchan ) ) + self.part_name( words[3], kchan ) # manual stop #self._stop = True #self.send('QUIT :stopped' ) @@ -195,7 +209,7 @@ class IrcProtocol( asyncio.Protocol ): #if 'PONG' not in msg: self.log( '>> {}'.format( msg ) ) self._trans.write( bytes( msg[:510] + '\r\n', 'utf-8' ) ) # helper func for sending a privmsg to specified destination - # also passes on to callbacks by default if not disabled + # also passes on to callbacks by default but can be disabled def say_to( self, dst, msg, callback=True ): msg = msg.replace( '\n', ' ' ).replace( '\r', '' ) self.log( '{} >> {}'.format( dst, msg ) )