Add event dispatcher module to allow modules to dispatch events and

to register handlers to listen for events.

Update IRCHandlers module to use new event dispatcher to dispatch
irc.events.  Update several modules to register with dispatcher
to listen for irc.events.

Improve handling of reconnection upon unexpected disconnection.

Todo: update more things to use new event dispatcher logic.
This commit is contained in:
Pragmatic Software 2014-11-01 00:15:21 +00:00
parent bc604d3ce2
commit d1e7abc175
8 changed files with 249 additions and 176 deletions

View File

@ -77,6 +77,8 @@ sub initialize {
$self->{pbot}->{commands}->register(sub { return $self->unbanme(@_) }, "unbanme", 0);
$self->{pbot}->{commands}->register(sub { return $self->whitelist(@_) }, "whitelist", 10);
$self->{pbot}->{event_dispatcher}->register_handler('irc.whoisaccount', sub { $self->on_whoisaccount(@_) });
}
sub ban_whitelisted {
@ -735,12 +737,13 @@ sub check_nickserv_accounts {
}
sub on_whoisaccount {
my ($self, $conn, $event) = @_;
my $nick = $event->{args}[1];
my $account = lc $event->{args}[2];
my ($self, $event_type, $event) = @_;
my $nick = $event->{event}->{args}[1];
my $account = lc $event->{event}->{args}[2];
$self->{pbot}->{logger}->log("$nick is using NickServ account [$account]\n");
$self->check_nickserv_accounts($nick, $account);
return 0;
}
sub adjust_offenses {

View File

@ -31,14 +31,16 @@ sub new {
sub initialize {
my ($self, %conf) = @_;
my $pbot = delete $conf{pbot} // Carp::croak("Missing pbot reference to BanTracker");
$self->{pbot} = $pbot;
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to BanTracker");
$self->{banlist} = {};
$self->{pbot}->{registry}->add_default('text', 'bantracker', 'chanserv_ban_timeout', '604800');
$pbot->{commands}->register(sub { return $self->dumpbans(@_) }, "dumpbans", 60);
$self->{pbot}->{commands}->register(sub { $self->dumpbans(@_) }, "dumpbans", 60);
$self->{pbot}->{event_dispatcher}->register_handler('irc.endofnames', sub { $self->get_banlist(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.banlist', sub { $self->on_banlist_entry(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.quietlist', sub { $self->on_quietlist_entry(@_) });
}
sub dumpbans {
@ -49,14 +51,43 @@ sub dumpbans {
}
sub get_banlist {
my ($self, $conn, $event) = @_;
my $channel = lc $event->{args}[1];
my ($self, $event_type, $event) = @_;
my $channel = lc $event->{event}->{args}[1];
delete $self->{banlist}->{$channel};
$self->{pbot}->{logger}->log("Retrieving banlist for $channel.\n");
$conn->sl("mode $channel +b");
$conn->sl("mode $channel +q");
$event->{conn}->sl("mode $channel +b");
$event->{conn}->sl("mode $channel +q");
return 0;
}
sub on_banlist_entry {
my ($self, $event_type, $event) = @_;
my $channel = lc $event->{event}->{args}[1];
my $target = lc $event->{event}->{args}[2];
my $source = lc $event->{event}->{args}[3];
my $timestamp = $event->{event}->{args}[4];
my $ago = ago(gettimeofday - $timestamp);
$self->{pbot}->{logger}->log("ban-tracker: [banlist entry] $channel: $target banned by $source $ago.\n");
$self->{banlist}->{$channel}->{'+b'}->{$target} = [ $source, $timestamp ];
return 0;
}
sub on_quietlist_entry {
my ($self, $event_type, $event) = @_;
my $channel = lc $event->{event}->{args}[1];
my $target = lc $event->{event}->{args}[3];
my $source = lc $event->{event}->{args}[4];
my $timestamp = $event->{event}->{args}[5];
my $ago = ago(gettimeofday - $timestamp);
$self->{pbot}->{logger}->log("ban-tracker: [quietlist entry] $channel: $target quieted by $source $ago.\n");
$self->{banlist}->{$channel}->{'+q'}->{$target} = [ $source, $timestamp ];
return 0;
}
sub get_baninfo {
@ -102,32 +133,6 @@ sub get_baninfo {
return $bans;
}
sub on_quietlist_entry {
my ($self, $conn, $event) = @_;
my $channel = lc $event->{args}[1];
my $target = lc $event->{args}[3];
my $source = lc $event->{args}[4];
my $timestamp = $event->{args}[5];
my $ago = ago(gettimeofday - $timestamp);
$self->{pbot}->{logger}->log("ban-tracker: [quietlist entry] $channel: $target quieted by $source $ago.\n");
$self->{banlist}->{$channel}->{'+q'}->{$target} = [ $source, $timestamp ];
}
sub on_banlist_entry {
my ($self, $conn, $event) = @_;
my $channel = lc $event->{args}[1];
my $target = lc $event->{args}[2];
my $source = lc $event->{args}[3];
my $timestamp = $event->{args}[4];
my $ago = ago(gettimeofday - $timestamp);
$self->{pbot}->{logger}->log("ban-tracker: [banlist entry] $channel: $target banned by $source $ago.\n");
$self->{banlist}->{$channel}->{'+b'}->{$target} = [ $source, $timestamp ];
}
sub track_mode {
my $self = shift;
my ($source, $mode, $target, $channel) = @_;

48
PBot/EventDispatcher.pm Normal file
View File

@ -0,0 +1,48 @@
package PBot::EventDispatcher;
use warnings;
use strict;
use IO::Select;
use Carp ();
sub new {
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference") if ref($_[1]) eq 'HASH';
my ($class, %conf) = @_;
my $self = bless {}, $class;
$self->initialize(%conf);
return $self;
}
sub initialize {
my ($self, %conf) = @_;
$self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference in " . __FILE__);
$self->{handlers} = { any => [] };
}
sub register_handler {
my ($self, $event_type, $sub) = @_;
push @{$self->{handlers}->{$event_type}}, $sub;
}
sub dispatch_event {
my ($self, $event_type, $event_data) = @_;
my $ret = undef;
if (exists $self->{handlers}->{$event_type}) {
foreach my $handler (@{$self->{handlers}->{$event_type}}) {
$ret = $handler->($event_type, $event_data);
return $ret if $ret;
}
}
foreach my $handler (@{$self->{handlers}->{any}}) {
$ret = $handler->($event_type, $event_data);
return $ret if $ret;
}
return $ret;
}
1;

View File

@ -14,7 +14,7 @@ use Data::Dumper;
sub new {
if(ref($_[1]) eq 'HASH') {
Carp::croak("Options to IRCHandlers should be key/value pairs, not hash reference");
Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference");
}
my ($class, %conf) = @_;
@ -27,34 +27,34 @@ sub new {
sub initialize {
my ($self, %conf) = @_;
my $pbot = delete $conf{pbot};
Carp::croak("Missing pbot parameter to IRCHandlers") if not defined $pbot;
$self->{pbot} = delete $conf{pbot};
Carp::croak("Missing pbot parameter to " . __FILE__) if not defined $self->{pbot};
$self->{pbot} = $pbot;
$self->{pbot}->{event_dispatcher}->register_handler('irc.welcome', sub { $self->on_connect(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.disconnect', sub { $self->on_disconnect(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.motd', sub { $self->on_motd(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.notice', sub { $self->on_notice(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.public', sub { $self->on_public(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.caction', sub { $self->on_action(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.msg', sub { $self->on_msg(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.mode', sub { $self->on_mode(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.part', sub { $self->on_departure(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.join', sub { $self->on_join(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.kick', sub { $self->on_kick(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.quit', sub { $self->on_departure(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.nick', sub { $self->on_nickchange(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.bannickchange', sub { $self->on_bannickchange(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.notregistered', sub { $self->on_notregistered(@_) });
}
sub default_handler {
my ($self, $conn, $event) = @_;
if ($self->{pbot}->{registry}->get_value('irc', 'log_default_handler')) {
my $dump = Dumper $event;
$self->{pbot}->{logger}->log($dump);
}
}
sub on_connect {
my ($self, $conn) = @_;
$self->{pbot}->{logger}->log("Connected!\n");
$conn->{connected} = 1;
}
sub on_disconnect {
my ($self, $conn, $event) = @_;
$self->{pbot}->{logger}->log("Disconnected, attempting to reconnect...\n");
$conn->connect();
if(not $conn->connected) {
sleep(5);
$self->on_disconnect($self, $conn, $event);
if(not defined $self->{pbot}->{event_dispatcher}->dispatch_event("irc.$event->{type}", { conn => $conn, event => $event })) {
if ($self->{pbot}->{registry}->get_value('irc', 'log_default_handler')) {
my $dump = Dumper $event;
$self->{pbot}->{logger}->log($dump);
}
}
}
@ -65,76 +65,95 @@ sub on_init {
$self->{pbot}->{logger}->log("*** @args\n");
}
sub on_connect {
my ($self, $event_type, $event) = @_;
$self->{pbot}->{logger}->log("Connected!\n");
$event->{conn}->{connected} = 1;
return 0;
}
sub on_disconnect {
my ($self, $event_type, $event) = @_;
$self->{pbot}->{logger}->log("Disconnected...\n");
$self->{pbot}->{connected} = 0;
return 0;
}
sub on_motd {
my ($self, $conn, $event) = @_;
my ($self, $event_type, $event) = @_;
if ($self->{pbot}->{registry}->get_value('irc', 'show_motd')) {
my $server = $event->{from};
my $msg = $event->{args}[1];
my $server = $event->{event}->{from};
my $msg = $event->{event}->{args}[1];
$self->{pbot}->{logger}->log("MOTD from $server :: $msg\n");
}
return 0;
}
sub on_public {
my ($self, $conn, $event) = @_;
my ($self, $event_type, $event) = @_;
my $from = $event->{to}[0];
my $nick = $event->nick;
my $user = $event->user;
my $host = $event->host;
my $text = $event->{args}[0];
my $from = $event->{event}->{to}[0];
my $nick = $event->{event}->nick;
my $user = $event->{event}->user;
my $host = $event->{event}->host;
my $text = $event->{event}->{args}[0];
$self->{pbot}->{interpreter}->process_line($from, $nick, $user, $host, $text);
return 0;
}
sub on_msg {
my ($self, $conn, $event) = @_;
my ($nick, $host) = ($event->nick, $event->host);
my $text = $event->{args}[0];
my ($self, $event_type, $event) = @_;
my ($nick, $host) = ($event->{event}->nick, $event->{event}->host);
my $text = $event->{event}->{args}[0];
my $bot_trigger = $self->{pbot}->{registry}->get_value('general', 'trigger');
$text =~ s/^\Q$bot_trigger\E?(.*)/$bot_trigger$1/;
$event->{to}[0] = $nick;
$event->{args}[0] = $text;
$self->on_public($conn, $event);
$event->{event}->{to}[0] = $nick;
$event->{event}->{args}[0] = $text;
$self->on_public($event_type, $event);
return 0;
}
sub on_notice {
my ($self, $conn, $event) = @_;
my ($nick, $host) = ($event->nick, $event->host);
my $text = $event->{args}[0];
my ($self, $event_type, $event) = @_;
my ($nick, $host) = ($event->{event}->nick, $event->{event}->host);
my $text = $event->{event}->{args}[0];
$self->{pbot}->{logger}->log("Received NOTICE from $nick $host '$text'\n");
if($nick eq "NickServ" && $text =~ m/This nickname is registered/) {
if($nick eq 'NickServ' && $text =~ m/This nickname is registered/) {
$self->{pbot}->{logger}->log("Identifying with NickServ . . .\n");
$conn->privmsg("nickserv", "identify " . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
$event->{conn}->privmsg("nickserv", "identify " . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
}
if($nick eq "NickServ" && $text =~ m/You are now identified/) {
if($nick eq 'NickServ' && $text =~ m/You are now identified/) {
foreach my $chan (keys %{ $self->{pbot}->{channels}->{channels}->hash }) {
if($self->{pbot}->{channels}->{channels}->hash->{$chan}{enabled}) {
$self->{pbot}->{logger}->log("Joining channel: $chan\n");
$conn->join($chan);
$event->{conn}->join($chan);
}
}
$self->{pbot}->{joined_channels} = 1;
}
return 0;
}
sub on_action {
my ($self, $conn, $event) = @_;
my ($self, $event_type, $event) = @_;
$event->{args}[0] = "/me " . $event->{args}[0];
$event->{event}->{args}[0] = "/me " . $event->{event}->{args}[0];
$self->on_public($conn, $event);
$self->on_public($event_type, $event);
return 0;
}
sub on_mode {
my ($self, $conn, $event) = @_;
my ($nick, $user, $host) = ($event->nick, $event->user, $event->host);
my $mode_string = $event->{args}[0];
my $channel = $event->{to}[0];
my ($self, $event_type, $event) = @_;
my ($nick, $user, $host) = ($event->{event}->nick, $event->{event}->user, $event->{event}->host);
my $mode_string = $event->{event}->{args}[0];
my $channel = $event->{event}->{to}[0];
$channel = lc $channel;
my ($mode, $modifier);
@ -150,7 +169,7 @@ sub on_mode {
}
$mode = $modifier . $char;
$target = $event->{args}[++$i];
$target = $event->{event}->{args}[++$i];
$self->{pbot}->{logger}->log("Got mode: source: $nick!$user\@$host, mode: $mode, target: " . (defined $target ? $target : "(undef)") . ", channel: $channel\n");
@ -171,7 +190,7 @@ sub on_mode {
}
elsif($mode eq "+b") {
$self->{pbot}->{logger}->log("Got banned in $channel, attempting unban.");
$conn->privmsg("chanserv", "unban $channel");
$event->{conn}->privmsg("chanserv", "unban $channel");
}
}
else { # bot not targeted
@ -187,19 +206,19 @@ sub on_mode {
foreach my $chan (keys %{ $self->{pbot}->{channels}->{channels}->hash }) {
if($self->{channels}->{channels}->hash->{$chan}{enabled}) {
$self->{pbot}->{logger}->log("Joining channel: $chan\n");
$self->{pbot}->{conn}->join($chan);
$event->{conn}->join($chan);
}
}
$self->{pbot}->{joined_channels} = 1;
}
}
}
return 0;
}
sub on_join {
my ($self, $conn, $event) = @_;
my ($nick, $user, $host, $channel) = ($event->nick, $event->user, $event->host, $event->to);
my ($self, $event_type, $event) = @_;
my ($nick, $user, $host, $channel) = ($event->{event}->nick, $event->{event}->user, $event->{event}->host, $event->{event}->to);
my $message_account = $self->{pbot}->{messagehistory}->get_message_account($nick, $user, $host);
$self->{pbot}->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $channel, "JOIN", $self->{pbot}->{messagehistory}->{MSG_JOIN});
@ -207,11 +226,12 @@ sub on_join {
$self->{pbot}->{registry}->get_value('antiflood', 'join_flood_threshold'),
$self->{pbot}->{registry}->get_value('antiflood', 'join_flood_time_threshold'),
$self->{pbot}->{messagehistory}->{MSG_JOIN});
return 0;
}
sub on_kick {
my ($self, $conn, $event) = @_;
my ($nick, $user, $host, $target, $channel, $reason) = ($event->nick, $event->user, $event->host, $event->to, $event->{args}[0], $event->{args}[1]);
my ($self, $event_type, $event) = @_;
my ($nick, $user, $host, $target, $channel, $reason) = ($event->{event}->nick, $event->{event}->user, $event->{event}->host, $event->{event}->to, $event->{event}->{args}[0], $event->{event}->{args}[1]);
$self->{pbot}->{logger}->log("$nick!$user\@$host kicked $target from $channel ($reason)\n");
@ -237,13 +257,14 @@ sub on_kick {
my $text = "KICKED " . (defined $hostmask ? $hostmask : $target) . " from $channel ($reason)";
$self->{pbot}->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $channel, $text, $self->{pbot}->{messagehistory}->{MSG_CHAT});
}
return 0;
}
sub on_departure {
my ($self, $conn, $event) = @_;
my ($nick, $user, $host, $channel, $args) = ($event->nick, $event->user, $event->host, $event->to, $event->args);
my ($self, $event_type, $event) = @_;
my ($nick, $user, $host, $channel, $args) = ($event->{event}->nick, $event->{event}->user, $event->{event}->host, $event->{event}->to, $event->{event}->args);
my $text = uc $event->type;
my $text = uc $event->{event}->type;
$text .= " $args";
my $message_account = $self->{pbot}->{messagehistory}->get_message_account($nick, $user, $host);
@ -270,31 +291,12 @@ sub on_departure {
$self->{pbot}->{logger}->log("Logged out $nick.\n");
delete $admin->{loggedin};
}
}
sub on_notregistered {
my ($self, $conn, $event) = @_;
my ($addr, $msg) = $event->args;
$self->{pbot}->{logger}->log("Received NOTREGISTERED from $addr: $msg\n");
$conn->privmsg("nickserv", "ghost " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
$conn->privmsg("nickserv", "release " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
$conn->privmsg("nickserv", "identify " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
}
sub on_bannickchange {
my ($self, $conn, $event) = @_;
my ($addr, $nick, $msg) = $event->args;
$self->{pbot}->{logger}->log("Received BANNICKCHANGE from $addr: $nick ($msg)\n");
$conn->privmsg("nickserv", "ghost " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
$conn->privmsg("nickserv", "release " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
$conn->privmsg("nickserv", "identify " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
return 0;
}
sub on_nickchange {
my ($self, $conn, $event) = @_;
my ($nick, $user, $host, $newnick) = ($event->nick, $event->user, $event->host, $event->args);
my ($self, $event_type, $event) = @_;
my ($nick, $user, $host, $newnick) = ($event->{event}->nick, $event->{event}->user, $event->{event}->host, $event->{event}->args);
$self->{pbot}->{logger}->log("$nick!$user\@$host changed nick to $newnick\n");
@ -314,6 +316,30 @@ sub on_nickchange {
$self->{pbot}->{registry}->get_value('antiflood', 'nick_flood_threshold'),
$self->{pbot}->{registry}->get_value('antiflood', 'nick_flood_time_threshold'),
$self->{pbot}->{messagehistory}->{MSG_NICKCHANGE});
return 0;
}
# todo: fix the following two subroutines so they work properly (e.g., change nick to randomly generated nick and await responses)
sub on_notregistered {
my ($self, $event_type, $event) = @_;
my ($addr, $msg) = $event->{event}->args;
$self->{pbot}->{logger}->log("Received NOTREGISTERED from $addr: $msg\n");
$event->{conn}->privmsg("nickserv", "ghost " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
$event->{conn}->privmsg("nickserv", "release " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
$event->{conn}->privmsg("nickserv", "identify " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
return 0;
}
sub on_bannickchange {
my ($self, $event_type, $event) = @_;
my ($addr, $nick, $msg) = $event->{event}->args;
$self->{pbot}->{logger}->log("Received BANNICKCHANGE from $addr: $nick ($msg)\n");
$event->{conn}->privmsg("nickserv", "ghost " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
$event->{conn}->privmsg("nickserv", "release " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
$event->{conn}->privmsg("nickserv", "identify " . $self->{pbot}->{registry}->get_value('irc', 'botnick') . ' ' . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
return 0;
}
1;

View File

@ -148,6 +148,7 @@ sub check_ignore {
}
}
=cut
if(exists $self->{ignore_flood_counter}->{$channel} and $self->{ignore_flood_counter}->{$channel} > 5) {
$self->{commands}->ignore_user("", "floodcontrol", "", "", ".* $channel 300");
$self->{ignore_flood_counter}->{$channel} = 0;
@ -157,6 +158,7 @@ sub check_ignore {
return 1;
}
}
=cut
}
foreach my $ignored (keys %{ $self->{ignore_list} }) {

View File

@ -33,6 +33,12 @@ sub initialize {
my $pbot = delete $conf{pbot} // Carp::croak("Missing pbot reference to LagChecker");
$self->{pbot} = $pbot;
$self->{lag_average} = undef; # average of entries in lag history, in seconds
$self->{lag_string} = undef; # string representation of lag history and lag average
$self->{lag_history} = []; # history of previous PING/PONG timings
$self->{pong_received} = undef; # tracks pong replies; undef if no ping sent; 0 if ping sent but no pong reply yet; 1 if ping/pong completed
$self->{ping_send_time} = undef; # when last ping was sent
# maximum number of lag history entries to retain
$pbot->{registry}->add_default('text', 'lagchecker', 'lag_history_max', $conf{lag_history_max} // 3);
# lagging is true if lag_average reaches or exceeds this threshold, in seconds
@ -42,12 +48,6 @@ sub initialize {
$pbot->{registry}->add_trigger('lagchecker', 'lag_history_interval', sub { $self->lag_history_interval_trigger(@_) });
$self->{lag_average} = undef; # average of entries in lag history, in seconds
$self->{lag_string} = undef; # string representation of lag history and lag average
$self->{lag_history} = []; # history of previous PING/PONG timings
$self->{pong_received} = undef; # tracks pong replies; undef if no ping sent; 0 if ping sent but no pong reply yet; 1 if ping/pong completed
$self->{ping_send_time} = undef; # when last ping was sent
$pbot->{timer}->register(
sub { $self->send_ping },
$pbot->{registry}->get_value('lagchecker', 'lag_history_interval'),
@ -55,6 +55,8 @@ sub initialize {
);
$pbot->{commands}->register(sub { return $self->lagcheck(@_) }, "lagcheck", 0);
$self->{pbot}->{event_dispatcher}->register_handler('irc.pong', sub { $self->on_pong(@_) });
}
sub lag_history_interval_trigger {
@ -104,6 +106,7 @@ sub on_pong {
$self->{lag_average} = $lag_total / $len;
$self->{lag_string} .= "; average: $self->{lag_average}";
return 0;
}
sub lagging {

View File

@ -30,6 +30,7 @@ use PBot::Registry;
use PBot::SelectHandler;
use PBot::StdinReader;
use PBot::IRC;
use PBot::EventDispatcher;
use PBot::IRCHandlers;
use PBot::Channels;
use PBot::BanTracker;
@ -98,20 +99,21 @@ sub initialize {
$self->{registry}->add_trigger('irc', 'botnick', sub { $self->change_botnick_trigger(@_) });
$self->{registry}->add_trigger('irc', 'debug', sub { $self->irc_debug_trigger(@_) });
$self->{select_handler} = PBot::SelectHandler->new(pbot => $self, %conf);
$self->{stdin_reader} = PBot::StdinReader->new(pbot => $self, %conf);
$self->{admins} = PBot::BotAdmins->new(pbot => $self, filename => delete $conf{admins_file}, %conf);
$self->{bantracker} = PBot::BanTracker->new(pbot => $self, %conf);
$self->{lagchecker} = PBot::LagChecker->new(pbot => $self, %conf);
$self->{messagehistory} = PBot::MessageHistory->new(pbot => $self, filename => delete $conf{messagehistory_file}, %conf);
$self->{antiflood} = PBot::AntiFlood->new(pbot => $self, %conf);
$self->{ignorelist} = PBot::IgnoreList->new(pbot => $self, filename => delete $conf{ignorelist_file}, %conf);
$self->{irc} = PBot::IRC->new();
$self->{irchandlers} = PBot::IRCHandlers->new(pbot => $self, %conf);
$self->{channels} = PBot::Channels->new(pbot => $self, filename => delete $conf{channels_file}, %conf);
$self->{chanops} = PBot::ChanOps->new(pbot => $self, %conf);
$self->{event_dispatcher} = PBot::EventDispatcher->new(pbot => $self, %conf);
$self->{select_handler} = PBot::SelectHandler->new(pbot => $self, %conf);
$self->{stdin_reader} = PBot::StdinReader->new(pbot => $self, %conf);
$self->{admins} = PBot::BotAdmins->new(pbot => $self, filename => delete $conf{admins_file}, %conf);
$self->{bantracker} = PBot::BanTracker->new(pbot => $self, %conf);
$self->{lagchecker} = PBot::LagChecker->new(pbot => $self, %conf);
$self->{messagehistory} = PBot::MessageHistory->new(pbot => $self, filename => delete $conf{messagehistory_file}, %conf);
$self->{antiflood} = PBot::AntiFlood->new(pbot => $self, %conf);
$self->{ignorelist} = PBot::IgnoreList->new(pbot => $self, filename => delete $conf{ignorelist_file}, %conf);
$self->{irc} = PBot::IRC->new();
$self->{irchandlers} = PBot::IRCHandlers->new(pbot => $self, %conf);
$self->{channels} = PBot::Channels->new(pbot => $self, filename => delete $conf{channels_file}, %conf);
$self->{chanops} = PBot::ChanOps->new(pbot => $self, %conf);
$self->{interpreter} = PBot::Interpreter->new(pbot => $self, %conf);
$self->{interpreter} = PBot::Interpreter->new(pbot => $self, %conf);
$self->{interpreter}->register(sub { return $self->{commands}->interpreter(@_); });
$self->{interpreter}->register(sub { return $self->{factoids}->interpreter(@_); });
@ -156,43 +158,24 @@ sub connect {
$self->{logger}->log("Connecting to $server ...\n");
$self->{conn} = $self->{irc}->newconn(
Nick => $self->{registry}->get_value('irc', 'botnick'),
Username => $self->{registry}->get_value('irc', 'username'),
Ircname => $self->{registry}->get_value('irc', 'ircname'),
Server => $server,
SSL => $self->{registry}->get_value('irc', 'SSL'),
SSL_ca_file => $self->{registry}->get_value('irc', 'SSL_ca_file'),
SSL_ca_path => $self->{registry}->get_value('irc', 'SSL_ca_path'),
Port => $self->{registry}->get_value('irc', 'port'))
or Carp::croak "$0: Can't connect to IRC server.\n";
while (not $self->{conn} = $self->{irc}->newconn(
Nick => $self->{registry}->get_value('irc', 'botnick'),
Username => $self->{registry}->get_value('irc', 'username'),
Ircname => $self->{registry}->get_value('irc', 'ircname'),
Server => $server,
SSL => $self->{registry}->get_value('irc', 'SSL'),
SSL_ca_file => $self->{registry}->get_value('irc', 'SSL_ca_file'),
SSL_ca_path => $self->{registry}->get_value('irc', 'SSL_ca_path'),
Port => $self->{registry}->get_value('irc', 'port'))) {
$self->{logger}->log("$0: Can't connect to IRC server. Retrying in 15 seconds...\n");
sleep 15;
}
$self->{connected} = 1;
#set up handlers for the IRC engine
$self->{conn}->add_default_handler(sub { $self->{irchandlers}->default_handler(@_) }, 1);
$self->{conn}->add_handler([ 251,252,253,254,302,255 ], sub { $self->{irchandlers}->on_init(@_) });
$self->{conn}->add_handler(376 , sub { $self->{irchandlers}->on_connect(@_) });
$self->{conn}->add_handler('disconnect' , sub { $self->{irchandlers}->on_disconnect(@_) });
$self->{conn}->add_handler('motd' , sub { $self->{irchandlers}->on_motd(@_) });
$self->{conn}->add_handler('notice' , sub { $self->{irchandlers}->on_notice(@_) });
$self->{conn}->add_handler('caction' , sub { $self->{irchandlers}->on_action(@_) });
$self->{conn}->add_handler('public' , sub { $self->{irchandlers}->on_public(@_) });
$self->{conn}->add_handler('msg' , sub { $self->{irchandlers}->on_msg(@_) });
$self->{conn}->add_handler('mode' , sub { $self->{irchandlers}->on_mode(@_) });
$self->{conn}->add_handler('part' , sub { $self->{irchandlers}->on_departure(@_) });
$self->{conn}->add_handler('join' , sub { $self->{irchandlers}->on_join(@_) });
$self->{conn}->add_handler('kick' , sub { $self->{irchandlers}->on_kick(@_) });
$self->{conn}->add_handler('quit' , sub { $self->{irchandlers}->on_departure(@_) });
$self->{conn}->add_handler('nick' , sub { $self->{irchandlers}->on_nickchange(@_) });
$self->{conn}->add_handler('pong' , sub { $self->{lagchecker}->on_pong(@_) });
$self->{conn}->add_handler('whoisaccount' , sub { $self->{antiflood}->on_whoisaccount(@_) });
$self->{conn}->add_handler('banlist' , sub { $self->{bantracker}->on_banlist_entry(@_) });
$self->{conn}->add_handler('endofnames' , sub { $self->{bantracker}->get_banlist(@_) });
$self->{conn}->add_handler(728 , sub { $self->{bantracker}->on_quietlist_entry(@_) });
$self->{conn}->add_handler('bannickchange' , sub { $self->{irchandlers}->on_bannickchange(@_) });
$self->{conn}->add_handler('notregistered' , sub { $self->{irchandlers}->on_notregistered(@_) });
$self->{conn}->add_handler([ 251,252,253,254,255,302 ], sub { $self->{irchandlers}->on_init(@_) });
# ignore these events
$self->{conn}->add_handler(['whoisuser',
@ -202,6 +185,7 @@ sub connect {
'whoisidle',
'endofwhois',
'motdstart',
'endofmotd',
'away',
'endofbanlist'], sub {});
}
@ -215,8 +199,10 @@ sub do_one_loop {
sub start {
my $self = shift;
$self->connect() if not $self->{connected};
while(1) { $self->do_one_loop(); }
while(1) {
$self->connect() if not $self->{connected};
$self->do_one_loop() if $self->{connected};
}
}
sub register_signal_handlers {

View File

@ -13,7 +13,7 @@ use warnings;
# These are set automatically by the build/commit script
use constant {
BUILD_NAME => "PBot",
BUILD_REVISION => 798,
BUILD_REVISION => 799,
BUILD_DATE => "2014-10-31",
};