IRC-Bot
view release on metacpan or search on metacpan
use POSIX qw( setsid );
use IRC::Bot::Log;
use IRC::Bot::Seen;
use IRC::Bot::Auth;
use IRC::Bot::Help;
use IRC::Bot::Quote;
use constant NICK => 'bot';
require Exporter;
@ISA = qw(Exporter AutoLoader);
@EXPORT = qw();
$VERSION = '0.07';
# Set us up the bomb
sub new {
my $class = shift;
my %args = @_;
return bless \%args, $class;
}
# Run the bot
sub run {
my $self = shift;
if ($self->{'LogPath'} eq '') {
$self->{'LogPath'} = $ENV{'HOME'} . "/";
}
$log = IRC::Bot::Log->new( 'Path' => $self->{'LogPath'} );
$seen = IRC::Bot::Seen->new();
$auth = IRC::Bot::Auth->new();
$help = IRC::Bot::Help->new();
$quote = IRC::Bot::Quote->new();
POE::Component::IRC->new(NICK)
|| croak "Cannot create new P::C::I object!\n";
POE::Session->create(
object_states => [
$self => {
_start => "bot_start",
irc_001 => "on_connect",
irc_disconnected => "on_disco",
irc_public => "on_public",
irc_msg => "on_msg",
irc_quit => "on_quit",
irc_join => "on_join",
irc_part => "on_part",
irc_mode => "on_mode",
irc_kick => "on_kick",
irc_notice => "on_notice",
irc_ctcp_ping => "on_ping",
irc_ctcp_version => "on_ver",
irc_ctcp_finger => "on_finger",
irc_ctcp_page => "on_page",
irc_ctcp_time => "on_time",
irc_ctcp_action => "on_action",
irc_nick => "on_nick",
keepalive => "keepalive",
irc_433 => "on_nick_taken",
irc_353 => "on_names",
irc_dcc_request => "on_dcc_req",
irc_dcc_error => "on_dcc_err",
irc_dcc_done => "on_dcc_done",
irc_dcc_start => "on_dcc_start",
irc_dcc_chat => "on_dcc_chat",
}
]
);
$poe_kernel->run();
}
# Start the bot things up
sub bot_start {
my ( $self, $kernel, $session ) = @_[ OBJECT, KERNEL, SESSION ];
my $ts = scalar(localtime);
$log->serv_log("[$ts] Starting Up...");
$kernel->post( NICK, 'register', 'all' );
$kernel->post(
NICK,
'connect',
{
Debug => $self->{'Debug'},
Nick => $self->{'Nick'},
Server => $self->{'Server'},
Port => $self->{'Port'},
Username => $self->{'Username'},
Password => $self->{'Password'},
Ircname => $self->{'Ircname'},
NSPass => $self->{'NSPass'}
}
);
$kernel->delay( 'reconnect', 20 );
}
# Handle connect event
# Join specified channels
sub on_connect {
my ( $self, $kernel ) = @_[ OBJECT, KERNEL ];
$kernel->post( NICK, 'mode', $self->{'Nick'}, '+B' );
if ($self->{'NSPass'}) {
my $msg = "identify " . $self->{'NSPass'};
$self->botspeak( $kernel, 'NickServ', $msg );
}
foreach my $chan ( @{ $self->{'Channels'} } ) {
$kernel->post( NICK, 'join', $chan );
}
}
# Someone pinged us, handle it.
sub on_ping {
my ( $self, $kernel, $who ) = @_[ OBJECT, KERNEL, ARG0 ];
my $nick = ( split /!/, $who )[0];
my $time = sprintf( "%02d:%02d", ( localtime( time() ) )[ 2, 1 ] );
$log->chan_log("[$chan $time] KICK: $nick: $kickee ($msg)");
}
# Handle someone quitting.
sub on_quit {
my ( $self, $kernel, $who, $msg ) = @_[ OBJECT, KERNEL, ARG0, ARG1 ];
my $nick = ( split /!/, $who )[0];
my $time = sprintf( "%02d:%02d", ( localtime( time() ) )[ 2, 1 ] );
$log->serv_log("[$self->{'Nick'} $time] QUIT: $nick: $msg");
$seen->log_seen( $nick, "Quit: $msg" );
}
# Handle join event
sub on_join {
my ( $self, $kernel, $who, $where ) = @_[ OBJECT, KERNEL, ARG0, ARG1 ];
my $nick = ( split /!/, $who )[0];
my $time = sprintf( "%02d:%02d", ( localtime( time() ) )[ 2, 1 ] );
$log->chan_log("[$where $time] JOIN: $nick");
$seen->log_seen( $nick, "Joining $where" );
}
# Handle part event
sub on_part {
my ( $self, $kernel, $who, $where ) = @_[ OBJECT, KERNEL, ARG0, ARG1 ];
my $nick = ( split /!/, $who )[0];
my $time = sprintf( "%02d:%02d", ( localtime( time() ) )[ 2, 1 ] );
$log->chan_log("[$where $time] PART: $nick");
$seen->log_seen( $nick, "Parting $where" );
}
# Changes nick if current nick is taken
sub on_nick_taken {
my ( $self, $kernel ) = @_[ OBJECT, KERNEL ];
my $nick = $self->{'Nick'};
my $rnick = int( rand(999) );
$kernel->post( NICK, 'nick', "$nick$rnick" );
}
# Communicate with channel/nick
sub botspeak {
my ( $self, $kernel, $channel, $msg ) = @_;
$kernel->post( NICK, 'privmsg', $channel, $msg );
}
# Borrowed this code from another bot
# Can't for the life of me remember which one
# Please, let me know if it was you, so I can
# give props!!
sub keepalive {
my ( $self, $kernel, $heap ) = @_[ OBJECT, KERNEL, HEAP ];
$heap->{'keepalive_time'} += 180;
$kernel->alarm( 'keepalive' => $heap->{'keepalive_time'} );
$kernel->post( NICK, 'sl', 'PING ' . time() );
}
# Handle public events
sub on_public {
my ( $self, $kernel, $who, $where, $msg ) =
@_[ OBJECT, KERNEL, ARG0 .. $#_ ];
my $nick = ( split /!/, $who )[0];
my $channel = $where->[0];
my $pubmsg = $msg;
my $time = sprintf( "%02d:%02d", ( localtime( time() ) )[ 2, 1 ] );
$log->chan_log("[$channel $time] <$nick> $msg");
if ( $msg =~ m/^!help$/i ) {
my %pubHelp = $help->pub_help();
$self->botspeak( $kernel, $channel, "Here is the help you requested:" );
foreach my $keys ( keys %pubHelp ) {
$self->botspeak( $kernel, $channel, $pubHelp{$keys} );
}
}
elsif ( $msg =~ m/^!ping$/i ) {
$self->botspeak( $kernel, $channel, "Pong!" );
}
elsif ( $msg =~ m/^!uptime$/i ) {
my $time = sprintf( "%d Days, %02d:%02d:%02d",
( gmtime( time() - $^T ) )[ 7, 2, 1, 0 ] );
$self->botspeak( $kernel, $channel, "I've been up for $time" );
}
elsif ( $msg =~ m/^!seen/i ) {
my @arg = split ( / /, $msg );
my $name = $arg[1];
if ($name) {
my $fseen = $seen->get_seen($name) || undef;
if ( $name eq $nick ) {
$self->botspeak( $kernel, $channel,
"Looking for yourself, $nick?" );
}
elsif ( $name eq $self->{'Nick'} ) {
$self->botspeak( $kernel, $channel, "I'm right here, foo!" );
}
elsif ( defined $fseen ) {
$self->botspeak( $kernel, $channel, $fseen );
}
else {
$self->botspeak( $kernel, $channel,
"Sorry, $nick, I haven't seen $name." );
}
}
( run in 2.117 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )