Do you like writing bots for irc? Well, if you have ever had trouble parsing the lines sent from the server into data you can use, I have a solution. Just use this simple OO module, which exports two methods: new, and parse_line ... new creates an object, and parse_line splits up each line from the irc server into usable data that your bot can then react to. Have fun!
package Mind; use strict; use diagnostics; use warnings; use Data::Dumper; sub new { my $class = shift; my $self = { NICK => undef, HOST => undef, TYPE => undef, CHAN => undef, TEXT => undef }; bless $self, $class; return $self; } sub parse_line { my $self = shift; chop (my $line = shift); my ($i_nick, $i_host, $i_type, $i_chan, $i_text); ($i_chan, $i_text) = split(/ :/, $line); ($i_nick, $i_type, $i_chan) = split(/ /, $line); ($i_nick, $i_host) = split(/!/, $i_nick); $i_nick =~ s/://; $self->{NICK} = $i_nick; $self->{HOST} = $i_host; $self->{TYPE} = $i_type; $self->{CHAN} = $i_chan; $self->{TEXT} = $i_text; #print Dumper($self); #test return $self; } #add your own method here #to allow for your bot to #react to things that happen #in your channel like so: sub interact { #test ... my $self = shift; if ($self->{TEXT} =~ /hi shrax/gi && $self->{NICK} =~ /kenny/g +i) { my $self = "$self->{TYPE} $self->{CHAN} :$self- +>{NICK}, it works!"; return $self; } if ($self->{TEXT} =~ /how are you shrax/gi && $self->{NICK} =~ + /kenny/gi) { my $self = "$self->{TYPE} $self->{CHAN} :$self- +>{NICK}, I'm fine thank you!"; return $self; } } 1;

Replies are listed 'Best First'.
Re: A Quick OO Module for parsing lines from an IRC connection
by merlyn (Sage) on Aug 26, 2005 at 03:08 UTC
      Your suggestions have been duly noted. And, since I never would have been able to Learn Perl had it not been for the books you helped author I sincerely appreciate your advice. I am concerned though, about the state that the constructor is in now. It stil compiles and it also is scalable enough to provide for inheritance but I am wondering if there is something else I could do with it to improve it. Any thoughts?
        Howdy!

        May I recommend the book Perl Best Practices by TheDamian? It offers well considered and reasoned recommendations, with examples and explanations, in many areas of Perl usage, including module creation and OO style.

        yours,
        Michael
Re: A Quick OO Module for parsing lines from an IRC connection
by gargle (Chaplain) on Aug 26, 2005 at 19:05 UTC

    Now that brings back memories! Years and years ago I remember logging in on bitnet relay chat and using REXX for my bots. Nowadays we use perl of course :)

    Funny how we're able to run our own irc server nowadays!

    Here's some quick code to log on an irc server. It doesn't do much, it just logs in into room1 and exits

    #!/usr/bin/perl use strict; use warnings; use IO::Socket; my $line; my $pong = ""; my $sock = IO::Socket::INET->new('localhost:6667'); print "nick whateverhack\n"; print $sock "nick whateverhack\r"; PING: while (<$sock>) { print "$_\r"; if ( $_ =~ /^PING :(.*)\r$/ ) { $pong = $1; last PING; } } print "PONG :$pong\n"; print $sock "pong :$pong\r"; print "user wcn ignored v8 :hack\n"; print $sock "user wcn ignored v8 :hack\r"; MOTD: while (<$sock>) { print "$_\r"; last MOTD if ( $_ =~ / 376 / ) ; } print "join #room1\n"; print $sock "join #room1\r"; print "bye\n"; print $sock "bye\n";

      Yeah! I use IO::Socket for programming bots as well. I learned a lot about network socket programming that way and it was fun.

      I like the way you wrote the code for that bot, as well.

      The various bots I write all connect pretty much the same way. The problem I always had was getting mine to send an auth message to nickserv after it connected. That was a little tricky, bt I am getting better, slowly but surely ;)

      Regards,
      SoupNazi

      Visit us at irc.crazylogic.org #apartment411
      D A R K E M P I R E s u b n e t w o r k

        Just a litte fun:

        Ok, it needs a lot more, p.e. you could code the reading part in a thread to loose the blocking.

        Irc.pm
        package Irc; use strict; use warnings; use Carp; use IO::Socket; sub new { my $class = shift; my $server = shift; my $self = { SERVER => $server, MYSOCKET => undef, }; my $closure = sub { my $field = shift; if (@_) { $self->{$field} = shift; } return $self->{$field}; }; bless ($closure, $class); return $closure; } # a public getter for the SERVER variable sub server { &{ $_[0] }("SERVER") } # a private getter/setter for the SOCKET variable sub socket { caller(0) eq __PACKAGE__ || confess "socket is a private method"; &{ $_[0] }( "MYSOCKET", @_[1..$#_] ); } # log on sub connect { my $self = shift; my $socket = IO::Socket::INET->new( $self->server() ); $self->socket($socket); } # logoff sub disconnect { my $self = shift; my $sock = $self->socket; print $sock "exit\r"; close $sock; } # send (and automatically append \r) sub send { my $self = shift; my $text = shift; my $sock = $self->socket; print $text . "\n"; print $sock $text . "\r"; } # receive something from the server sub read { my $self = shift; my $sock = $self->socket; PINGPONG: while (<$sock>) { print "$_"; # break after receiving PING if (/^PING :(.+)\r$/) { $self->send("PONG :$1"); last PINGPONG; } # break after receiving MOTD if (/ 376/) { last PINGPONG; } } } 1;
        irc.pl
        #!/usr/bin/perl use strict; use warnings; use Irc; my $session = Irc->new("localhost:6667"); $session->connect(); $session->send("nick whatever"); $session->read(); $session->send("user whatever ignored v1.0 :perl hack"); $session->read(); $session->send("join #room1"); # now keep on reading until receiving the special logoff code ;) $session->read(); $session->disconnect();

        Something like this?

        my $sock = IO::Socket::INET->new('localhost:6669'); print "pass this_is_the_passwd\n"; print $sock "pass this_is_the_pw\r"; print "nick whateverhack\n"; print $sock "nick whateverhack\r";

        later on I always to stuff like this to parse messages people send (here p.e. all messages from hitty:

        LOOP: while (<$sock>) { $line = $_; if ( $line =~ / 366 / ) { print "$line\r"; } if ( $line =~ /PRIVMSG/ ) { $line =~ /^:(.*)!(.*) PRIVMSG (.*) :(.*?)--(.*).$/; $from = $1; $room = $3; $cam = $4; if ($cam eq "") { next LOOP; } $comment = $5; if ( $cam =~ /hitty/ ) { print "<$from\@$cam> $comment\n"; } } }