Swordkeeper has asked for the wisdom of the Perl Monks concerning the following question:

I was thinking about this, a friend did this code, and it works... just cant get on a chan 'yet'
#!/usr/bin/perl use IO::Socket; $s = IO::Socket::INET->new(Proto=>'tcp',PeerAddr=> 'irc.cyberarmy.com' +,PeerPort=> 6667); print $s "NICK b0t\nUSER b0t - - :b0t\n"; while($s) { my ($i,$j)= split/ /, $_ = <$s>; print; if ($_ eq 'PING') +{ print $s 'PONG '.$j;} }
I was thinking of doing it this way, to have it idle on a chan..here is my version
#!/usr/bin/perl use IO::Socket; #IO through sockets..;) $s = IO::Socket::INET->new(Proto=>'tcp',PeerAddr=> 'irc.dal.net',PeerP +ort=> 6667); #set up the server and info for the bot. print $s "NICK WhiteRav3n0wnz\nUSER b0t - - :b0t\n"; #Bot info to server. print $s "JOIN #hackerhost\n"; #Chan to enter. while($s){ #main bot loop my ($i,$j)= split/ /, $_ = <$s>; #split incomming text print; if ($_ eq 'PING') { #if you get a ping from the server, print $s 'PONG '.$j; #pong back.. } }
I havent had the time to really get into this, but it should work, based on what I can see from the IRC rfc (rfc 1459 if your interested), and would be interesting, since you could then run it from a server such as a free webhost that let you do cgi.. great in times nickserv or chanserv is offline, if it was alreaady idling with ops - then no-one could take over the chan from lack of chanserv or nickserv if no one was there.. has anybody has a simaler idea? I searched for something like this on perl monks, but I didnt find anything.. anybody got some ideas?

Replies are listed 'Best First'.
Re: IRC bot in perl
by gellyfish (Monsignor) on Mar 10, 2002 at 09:33 UTC

    This is a cut down version of the first bot I ever experimented with (with some stuff changed to protect the innocent:

    #!/usr/bin/perl -w use strict; use IO::Socket; my ( $server, $port, $my_nick, $channel, ) = ('irc.dal.net', 6667, 'foobot', '#hackerhost', ); my $sock = IO::Socket::INET->new(PeerAddr => $server, PeerPort => $port, Proto => "tcp", ); print $sock "USER $my_nick foo.wherever.com $server :Just another bot\ +n"; print $sock "NICK $my_nick\n"; $SIG{INT} = sub { print $sock "QUIT :Copped signint from owner\n"; close $sock; exit; }; SOCKLOOP: while (<$sock>) { if ( /^[A-Z]/ ) { if ( /^PING\s+:([\w.]+)/ ) { print $sock "PONG $1\n"; } next SOCKLOOP; #probably need to catch some other stuff but hey } else { my ($server,$action,$stuff) = /^:(\S+)\s+(\w+)\s+(.*)/; if ( $action =~ /\d+/ ) # Server response code { if ($action == 376 ) { print $sock "JOIN $channel\n"; } } } }
    This works and has been tested. The way I have done it gives you an opportunity to expand its functionality later.

    However having shown you that most people now will use Net::IRC or even better POE::Component::IRC because both of those will handle setting up the connection, joining the channel and answering the PINGs leaving you free to add the actual functionality.

    Of course all of this moot because if you are intending to run this as a CGI then it isn't going to work because a CGI program is started as the result of a request from a browser and is intended to return some content and then terminate, it will not maintain a permanent connection for you.

    /J\

      Well, as a cgi, I was thinking maybe use another cgi to start it using sytem calls, then return html code for a page saying it had been started right.. on error deleting the file or outputing the error codes through redirection of the ERR handle or some such.. mabey on die starting itself again; I still have allot to learn, But at least I admit my lack of perl wisdom and seek to learn more - Thank you for the links to the pm's, there were unknown to me and will provide a interesting study ;)

        I don't think this is so much of a lack of perl wisdom but is more to do with the way all the rest of it works. To do what you want you will need to fork() a child process - there are plenty of nodes like Re: Re: sending bulk emails in a specified time that explain how to do this in a CGI context, however the real issue is that on any properly administered web server the adminstrators are likely to notice your long running process and terminate it without mercy, some free web hosts even go as far as to disable things like fork() altogether as it is a reasonably dangerous thing to allow unknow users to do.

        /J\

Re: IRC bot in perl
by Juerd (Abbot) on Mar 10, 2002 at 12:39 UTC

    use IO::Socket;

    You're re-inventing the wheel. Use POE::Component::IRC instead, and make use of POE's beautiful Wheel.

    Net::IRC is another alternative, but it is out-dated.

    44696420796F7520732F2F2F65206F
    7220756E7061636B3F202F6D736720
    6D6521203A29202D2D204A75657264
    

      thank you for the input. I coded another version, but it has a bug.. Im chasing it down as I type this.. ;)