#FILE - IRC/Socket.pm
package IRC::Socket;
use strict;
use IO::Socket;
use IRC::Handler;
use Data::Dumper;
sub new {
my ($class, $server, $port) = @_;
$port ||= 6667;
my $self = {
server => $server,
port => $port,
count => {
sent => 0,
received => 0,
}
};
$self->{connected} = 0;
$self->{handler} = IRC::Handler->new($class);
$self->{commands} = IRC::Handler->new($class);
bless $self, $class;
return $self;
}
sub is_connected {
my $self = shift;
return $self->{connected};
}
sub add_handle {
my $self = shift;
my ($handle, $subref) = @_;
$self->{handler}->add_handle($handle, $subref);
}
sub add_command {
my $self = shift;
my ($command, $subref) = @_;
$self->{commands}->add_handle($command, $subref);
}
sub connect {
my $self = shift;
return if $self->is_connected();
my ($server, $port) = ($self->{server}, $self->{port});
if ($server && $port) {
$self->{sock} = IO::Socket::INET->new(
PeerAddr => $server,
PeerPort => $port,
Proto => 'tcp'
) || die "Unable to connect";
print "Connecting to $server:$port...n";
$self->{connected} = 1;
} else {
die("Server or port is undefined, cannot connect");
}
}
sub read {
my $self = shift;
return if !$self->is_connected();
my $line = $self->{sock}->getline;
chomp($line);
my @data = split(' ', $line, 4);
$self->write("PONG $data[1]") if ($data[0] eq 'PING');
if ($self->{handler}->has_handle($data[1])) {
$self->{handler}->exec_handle($data[1], $self);
}
if ($data[1] eq 'PRIVMSG') {
my $nick;
if ($data[0] =~ /^:(S+?)!/) { $nick = $1; }
my $chan = $data[2];
my $msg = $data[3];
$msg =~ s/^://;
my @msgargs = split(' ', $msg);
if ($self->{commands}->has_handle($msgargs[0])) {
my $command = $msgargs[0];
$msg =~ s/^$commands*//;
$self->{commands}->exec_handle($command, $self, $nick, $chan, $msg);
}
}
$self->{count}->{received}++;
return $line;
}
sub write {
my $self = shift;
my ($str) = @_;
return if !$self->is_connected();
$self->{count}->{sent}++;
$self->{sock}->print($str."rn");
}
# Login to our IRC server
sub login {
my $self = shift;
my ($nickname, $username, $realname, $serverpass) = @_;
$self->write("PASS $serverpass") if $serverpass;
$self->write("NICK $nickname");
$self->write("USER $username $nickname * :$realname");
}
sub privmsg {
my $self = shift;
my ($channel, $message) = @_;
$self->write("PRIVMSG $channel :$message");
}
sub notice {
my $self = shift;
my ($channel, $message) = @_;
$self->write("NOTICE $channel :$message");
}
sub identify {
my $self = shift;
my ($pass) = @_;
$self->privmsg('NickServ', "IDENTIFY $pass");
}
# Join a list of channels, if using a channel password
# use #channel:password
sub join {
my $self = shift;
for (@_) {
if (my $pass = $_ =~ /^#S+:(S+)$/) {
$self->write("JOIN $_ $pass");
} else {
$self->write("JOIN $_");
}
}
}
# Leave a list of channels
sub part {
my $self = shift;
my $reason = shift || 'Leaving..';
for (@_) {
$self->write("PART $_");
}
}
# Send our QUIT message and close our IRC connection
sub close {
my $self = shift;
return unless $self->is_connected();
$self->write("QUIT");
# close our IRC socket $self->{sock}
exit;
}
1;
#END FILE - IRC/Socket.pm
#FILE - IRC/Handler.pm
package IRC::Handler;
use strict;
sub new {
my $class = shift;
my $irc = shift;
my $self = {
hooks => {}
};
bless $self, $class;
return $self;
}
sub add_handle {
my $self = shift;
my ($key, $subref) = @_;
$self->{hooks}->{$key} = $subref;
}
sub exec_handle {
my $self = shift;
my $key = shift;
my ($irc, $nick, $chan, $msg) = @_;
my $subref = $self->{hooks}->{$key};
$subref->($irc, $nick, $chan, $msg);
}
sub has_handle {
my $self = shift;
my ($handle) = @_;
if (exists($self->{hooks}->{$handle})) {
return 1;
}
return;
}
1;
#END FILE - IRC/Handler.pm
#FILE - run.pl
#!/usr/bin/perl -w
use strict;
use warnings;
use IRC::Socket;
my $irc = IRC::Socket->new('irc.2600.net');
$irc->connect();
$irc->login('Sponge', 'Spongey', 'Sponge Bawb');
#$irc->identify('somepassword');
# adds a handle for end of MOTD
# and executes our 'join' subroutine
$irc->add_handle('376', &join);
$irc->add_command('!say', &say);
$irc->add_command('!die', &quit);
while (1) {
while ($irc->is_connected()) {
my $line = $irc->read();
print $line."n";
}
}
sub join {
my $irc = shift;
$irc->join('#sponge');
}
# !say foo bar baz
# bot replys back in channel with the text 'foo bar baz'
sub say {
my ($irc, $nick, $chan, $msg) = @_;
$irc->privmsg($chan, $msg);
}
# !quit
# bot quits the irc server
sub quit {
my $irc = shift;
$irc->quit();
}