Pergunta

I am trying to implement an IRC Bot on a local server. The bot that I am using is identical to the one found at Eric Florenzano's Blog. This is the simplified code (which should run)

import sys
import re
from twisted.internet import reactor
from twisted.words.protocols import irc
from twisted.internet import protocol

class MomBot(irc.IRCClient):
    def _get_nickname(self):
        return self.factory.nickname
    nickname = property(_get_nickname)

    def signedOn(self):
        print "attempting to sign on"
        self.join(self.factory.channel)
        print "Signed on as %s." % (self.nickname,)

    def joined(self, channel):
        print "attempting to join"
        print "Joined %s." % (channel,)

    def privmsg(self, user, channel, msg):
        if not user:
            return
        if self.nickname in msg:
            msg = re.compile(self.nickname + "[:,]* ?", re.I).sub('', msg)
            prefix = "%s: " % (user.split('!', 1)[0], )
        else:
            prefix = ''
        self.msg(self.factory.channel, prefix + "hello there")


class MomBotFactory(protocol.ClientFactory):
    protocol = MomBot

    def __init__(self, channel, nickname='YourMomDotCom', chain_length=3,
        chattiness=1.0, max_words=10000):
        self.channel = channel
        self.nickname = nickname
        self.chain_length = chain_length
        self.chattiness = chattiness
        self.max_words = max_words

    def startedConnecting(self, connector):
        print "started connecting on {0}:{1}" 
            .format(str(connector.host),str(connector.port))

    def clientConnectionLost(self, connector, reason):
        print "Lost connection (%s), reconnecting." % (reason,)
        connector.connect()

    def clientConnectionFailed(self, connector, reason):
        print "Could not connect: %s" % (reason,)

if __name__ == "__main__":
    chan = sys.argv[1]
    reactor.connectTCP("localhost", 6667, MomBotFactory('#' + chan,
        'YourMomDotCom', 2, chattiness=0.05))
    reactor.run()

I added the startedConnection method in the client factory, which it is reaching and printing out the proper address:host. It then disconnects and enters the clientConnectionLost and prints the error:

Lost connection ([Failure instance: Traceback (failure with no frames):
    <class 'twisted.internet.error.ConnectionDone'>: Connection was closed cleanly.
    ]), reconnecting.

If working properly it should log into the appropriate channel, specified as the first arg in the command (e.g. python module2.py botwar. would be channel #botwar.). It should respond with "hello there" if any one in the channel sends anything.

I have NGIRC running on the server, and it works if I connect from mIRC or any other IRC client.

I am unable to find a resolution as to why it is continually disconnecting. Any help on why would be greatly appreciated. Thank you!

Foi útil?

Solução

One thing you may want to do is make sure you will see any error output produced by the server when your bot connects to it. My hunch is that the problem has something to do with authentication, or perhaps an unexpected difference in how ngirc handles one of the login/authentication commands used by IRCClient.

One approach that almost always applies is to capture a traffic log. Use a tool like tcpdump or wireshark.

Another approach you can try is to enable logging inside the Twisted application itself. Use twisted.protocols.policies.TrafficLoggingFactory for this:

from twisted.protocols.policies import TrafficLoggingFactory
appFactory = MomBotFactory(...)
logFactory = TrafficLoggingFactory(appFactory, "irc-")
reactor.connectTCP(..., logFactory)

This will log output to files starting with "irc-" (a different file for each connection).

You can also hook directly into your protocol implementation, at any one of several levels. For example, to display any bytes received at all:

class MomBot(irc.IRCClient):
    def dataReceived(self, bytes):
        print "Got", repr(bytes)
        # Make sure to up-call - otherwise all of the IRC logic is disabled!
        return irc.IRCClient.dataReceived(self, bytes)

With one of those approaches in place, hopefully you'll see something like:

:irc.example.net 451 * :Connection not registered

which I think means... you need to authenticate? Even if you see something else, hopefully this will help you narrow in more closely on the precise cause of the connection being closed.

Also, you can use tcpdump or wireshark to capture the traffic log between ngirc and one of the working IRC clients (eg mIRC) and then compare the two logs. Whatever different commands mIRC is sending should make it clear what changes you need to make to your bot.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top