159 lines
4.3 KiB
Perl
159 lines
4.3 KiB
Perl
package CDBot;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use base qw(Bot::BasicBot);
|
|
|
|
use Time::Duration;
|
|
use Scalar::Util qw(looks_like_number);
|
|
use POE::Component::IRC::Common qw(:ALL);
|
|
use POE::Component::IRC::State;
|
|
use POE;
|
|
use List::Util qw/reduce/;
|
|
use Math::Random::MT;
|
|
use Random::Quantum;
|
|
use Data::Dumper;
|
|
|
|
print "Seeding the PRNG from Quantum Source\n";
|
|
my $cl = new Random::Quantum(user => 'simcop2387', 'password' => 'sindarin');
|
|
my $gen = Math::Random::MT->new($cl->int4);
|
|
print "Seeded!\n";
|
|
|
|
my $float = qr/[0-9]*(?:\.?[0-9]+)?(?:[eE][-+]?[0-9]+)?/;
|
|
|
|
my $startform = DARK_BLUE.",01". BOLD . "[ ". BOLD. RED;
|
|
my $endform = DARK_BLUE.BOLD." ]";
|
|
|
|
sub _frm { $startform.$_[0].$endform };
|
|
|
|
sub isallowed {
|
|
my $self = shift;
|
|
my $message = shift;
|
|
my ($who, $where) = @{$message}{"who","channel"};
|
|
my $state = $self->{IRCOBJ};
|
|
return 1 if ($state->is_channel_operator($where, $who) ||
|
|
$state->is_channel_admin($where, $who) ||
|
|
$state->is_channel_owner($where, $who) ||
|
|
$state->is_channel_halfop($where, $who));
|
|
return 0;
|
|
}
|
|
|
|
sub said {
|
|
my $self = shift;
|
|
my $message = shift;
|
|
my $body = $message->{body};
|
|
return if ($message->{channel} ne "msg" && $message->{channel} ne "#minimafia");
|
|
|
|
if ($body =~ /^!dice\s*(?:(\d+)d(\d+))?/) {
|
|
my ($dice, $sides) = ($1, $2);
|
|
$dice ||= 1; $sides ||= 6;
|
|
if ($dice >= 31) {
|
|
$self->reply($message, _frm "Can't use that many dice!");
|
|
return;
|
|
}
|
|
|
|
my @a = map {int($gen->rand($sides)+1)} (1..$dice);
|
|
my $sum = reduce {$a + $b} @a;
|
|
my $msg;
|
|
|
|
if ($dice == 1) {$msg = "You rolled a $sum";}
|
|
else {$msg = "You rolled ".join(" + ", @a)." = $sum";}
|
|
print "DICE ROLL: ", $msg, "\n";
|
|
$self->reply($message, _frm $msg);
|
|
}
|
|
|
|
return if (!$self->isallowed($message));
|
|
|
|
if ($self->{active} && $body =~ /^!endcount(down)?/) {
|
|
$self->{active} = 0;
|
|
$self->reply($message, _frm "Countdown ended");
|
|
} elsif (!$self->{active} && $body =~ /^!countdown(?:bot)?\s*(?:($float)\s*([hms])?)?/i) {
|
|
$self->{active} = 1;
|
|
|
|
my $number = $1;
|
|
my $scale = lc($2 || "");
|
|
my $end;
|
|
my %scales = (h => 60 * 60, m => 60, s => 1, undef => 60, "" => 60);
|
|
|
|
if (looks_like_number($number)) {
|
|
$end = $number * $scales{$scale};
|
|
} else {
|
|
$end = 15*60; # default to 15 minutes
|
|
}
|
|
|
|
$self->{time} = time+$end;
|
|
$self->reply($message, _frm "Will count down for ".duration($end));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
# Called 5 seconds after bot startup, and then called again 'x' seconds
|
|
# later, where 'x' is whatever the function returns.
|
|
sub tick {
|
|
my $self = shift;
|
|
|
|
if ($self->{active}) {
|
|
# How long till the event?
|
|
my $secs = $self->{time} - time;
|
|
|
|
# What will we say?
|
|
my $body = _frm (($secs > 0) ? duration($secs, 1)." to go" : "Time's up!");
|
|
|
|
# Say this thing in all our channels.
|
|
$self->say( channel => $_, body => $body ) for (@{$self->{channels}});
|
|
|
|
# Now, depending on how long is left, wait a different amount of
|
|
# time.
|
|
if ($secs > 60 * 30) {
|
|
return 60 * 10
|
|
} elsif ( $secs > 60 ) {
|
|
return 60
|
|
} elsif ( $secs > 10 ) {
|
|
return 10
|
|
} elsif ( $secs > 5 ) {
|
|
return 5
|
|
} elsif ( $secs > 0 ) {
|
|
return 1;
|
|
} else {
|
|
$self->{active} = 0;
|
|
return 10; # done.
|
|
}
|
|
} else {
|
|
return 10;
|
|
}
|
|
}
|
|
|
|
sub start_state {
|
|
my ( $self, $kernel, $session ) = @_[ OBJECT, KERNEL, SESSION ];
|
|
$self->{kernel} = $kernel;
|
|
$self->{session} = $session;
|
|
|
|
# Make an alias for our session, to keep it from getting GC'ed.
|
|
$kernel->alias_set($self->{ALIASNAME});
|
|
$kernel->delay('tick', 30);
|
|
|
|
$self->{IRCOBJ} = POE::Component::IRC::State->spawn( alias => $self->{IRCNAME} );
|
|
$self->{IRCOBJ}->plugin_add('Connector', POE::Component::IRC::Plugin::Connector->new());
|
|
$kernel->post( $self->{IRCNAME}, 'register', 'all' );
|
|
|
|
$kernel->post($self->{IRCNAME}, 'connect',
|
|
{
|
|
Debug => 0,
|
|
Nick => $self->nick,
|
|
Server => $self->server,
|
|
Port => $self->port,
|
|
Password => $self->password,
|
|
UseSSL => $self->ssl,
|
|
Flood => $self->flood,
|
|
$self->charset_encode(
|
|
Nick => $self->nick,
|
|
Username => $self->username,
|
|
Ircname => $self->name,
|
|
),
|
|
}
|
|
);
|
|
|
|
return;
|
|
}
|