diff --git a/PBot/AntiFlood.pm b/PBot/AntiFlood.pm index 1b2f417f..0de7ff7e 100644 --- a/PBot/AntiFlood.pm +++ b/PBot/AntiFlood.pm @@ -14,9 +14,6 @@ use strict; use feature 'switch'; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use PBot::DualIndexHashObject; use PBot::LagChecker; @@ -45,14 +42,10 @@ sub initialize { $self->{NICKSERV_VALIDATED} = (1<<0); $self->{NEEDS_CHECKBAN} = (1<<1); - $self->{ENTER_ABUSE_MAX_LINES} = 4; - $self->{ENTER_ABUSE_MAX_OFFENSES} = 3; - $self->{ENTER_ABUSE_MAX_SECONDS} = 20; - - $self->{channels} = {}; # per-channel statistics, e.g. for optimized tracking of last spoken nick for enter-abuse detection, etc + $self->{channels} = {}; # per-channel statistics, e.g. for optimized tracking of last spoken nick for enter-abuse detection, etc $self->{nickflood} = {}; # statistics to track nickchange flooding - my $filename = delete $conf{banwhitelist_file} // $self->{pbot}->{data_dir} . '/ban_whitelist'; + my $filename = delete $conf{banwhitelist_file} // $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/ban_whitelist'; $self->{ban_whitelist} = PBot::DualIndexHashObject->new(name => 'BanWhitelist', filename => $filename); $self->{ban_whitelist}->load; @@ -212,7 +205,7 @@ sub check_flood { } # do not do flood processing for bot messages - if($nick eq $self->{pbot}->botnick) { + if($nick eq $self->{pbot}->{registry}->get_value('irc', 'botnick')) { $self->{channels}->{$channel}->{last_spoken_nick} = $nick; return; } @@ -229,9 +222,9 @@ sub check_flood { } } - if($max_messages > $self->{pbot}->{MAX_NICK_MESSAGES}) { - $self->{pbot}->logger->log("Warning: max_messages greater than MAX_NICK_MESSAGES; truncating.\n"); - $max_messages = $self->{pbot}->{MAX_NICK_MESSAGES}; + if($max_messages > $self->{pbot}->{registry}->get_value('messagehistory', 'max_messages')) { + $self->{pbot}->logger->log("Warning: max_messages greater than max_messages limit; truncating.\n"); + $max_messages = $self->{pbot}->{registry}->get_value('messagehistory', 'max_messages'); } # check for ban evasion if channel begins with # (not private message) and hasn't yet been validated against ban evasion @@ -257,11 +250,15 @@ sub check_flood { if(defined $self->{channels}->{$channel}->{last_spoken_nick} and $nick eq $self->{channels}->{$channel}->{last_spoken_nick}) { my $messages = $self->{pbot}->{messagehistory}->{database}->get_recent_messages($account, $channel, 2, $self->{pbot}->{messagehistory}->{MSG_CHAT}); - if($messages->[1]->{timestamp} - $messages->[0]->{timestamp} <= $self->{ENTER_ABUSE_MAX_SECONDS}) { - if(++$channel_data->{enter_abuse} >= $self->{ENTER_ABUSE_MAX_LINES} - 1) { - $channel_data->{enter_abuse} = $self->{ENTER_ABUSE_MAX_LINES} / 2 - 1; - if(++$channel_data->{enter_abuses} >= $self->{ENTER_ABUSE_MAX_OFFENSES}) { - my $offenses = $channel_data->{enter_abuses} - $self->{ENTER_ABUSE_MAX_OFFENSES} + 1; + my $enter_abuse_max_lines = $self->{pbot}->{registry}->get_value('antiflood', 'enter_abuse_max_lines'); + my $enter_abuse_max_seconds = $self->{pbot}->{registry}->get_value('antiflood', 'enter_abuse_max_seconds'); + my $enter_abuse_max_offenses = $self->{pbot}->{registry}->get_value('antiflood', 'enter_abuse_max_offenses'); + + if($messages->[1]->{timestamp} - $messages->[0]->{timestamp} <= $enter_abuse_max_seconds) { + if(++$channel_data->{enter_abuse} >= $enter_abuse_max_lines - 1) { + $channel_data->{enter_abuse} = $enter_abuse_max_lines / 2 - 1; + if(++$channel_data->{enter_abuses} >= $enter_abuse_max_offenses) { + my $offenses = $channel_data->{enter_abuses} - $enter_abuse_max_offenses + 1; my $ban_length = $offenses ** $offenses * $offenses * 30; $self->{pbot}->chanops->ban_user_timed("*!$user\@$host", $channel, $ban_length); $ban_length = duration($ban_length); @@ -276,7 +273,7 @@ sub check_flood { $self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data); } else { if($channel_data->{enter_abuse} > 0) { - #$self->{pbot}->logger->log("$nick $channel more than $self->{ENTER_ABUSE_MAX_SECONDS} seconds since last message, enter abuse counter reset\n"); + #$self->{pbot}->logger->log("$nick $channel more than $enter_abuse_max_seconds seconds since last message, enter abuse counter reset\n"); $channel_data->{enter_abuse} = 0; $self->{pbot}->{messagehistory}->{database}->update_channel_data($account, $channel, $channel_data); } @@ -396,7 +393,7 @@ sub unbanme { my ($self, $from, $nick, $user, $host, $arguments) = @_; my $channel = lc $arguments; - if(not defined $arguments or not defined $channel) { + if(not $arguments or not $channel) { return "/msg $nick Usage: unbanme "; } diff --git a/PBot/BanTracker.pm b/PBot/BanTracker.pm index 674bbc0e..4bda8307 100644 --- a/PBot/BanTracker.pm +++ b/PBot/BanTracker.pm @@ -11,9 +11,6 @@ package PBot::BanTracker; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Time::HiRes qw/gettimeofday/; use Time::Duration; use Data::Dumper; diff --git a/PBot/BotAdminCommands.pm b/PBot/BotAdminCommands.pm index 8befc59b..a0eed4de 100644 --- a/PBot/BotAdminCommands.pm +++ b/PBot/BotAdminCommands.pm @@ -8,9 +8,6 @@ package PBot::BotAdminCommands; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Carp (); sub new { diff --git a/PBot/BotAdmins.pm b/PBot/BotAdmins.pm index 1ca4c57a..31702648 100644 --- a/PBot/BotAdmins.pm +++ b/PBot/BotAdmins.pm @@ -8,9 +8,6 @@ package PBot::BotAdmins; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use PBot::DualIndexHashObject; use Carp (); @@ -58,7 +55,7 @@ sub initialize { sub add_admin { my $self = shift; - my ($name, $channel, $hostmask, $level, $password) = @_; + my ($name, $channel, $hostmask, $level, $password, $dont_save) = @_; $channel = lc $channel; $hostmask = lc $hostmask; @@ -69,7 +66,7 @@ sub add_admin { $self->{pbot}->logger->log("Adding new level $level admin: [$name] [$hostmask] for channel [$channel]\n"); - $self->save_admins; + $self->save_admins unless $dont_save; } sub remove_admin { @@ -144,7 +141,7 @@ sub export_admins { sub find_admin { my ($self, $from, $hostmask) = @_; - $from = $self->{pbot}->botnick if not defined $from; + $from = $self->{pbot}->{registry}->get_value('irc', 'botnick') if not defined $from; $hostmask = '.*' if not defined $hostmask; my $result = eval { diff --git a/PBot/ChanOpCommands.pm b/PBot/ChanOpCommands.pm index 9b42d11b..cc92f4d5 100644 --- a/PBot/ChanOpCommands.pm +++ b/PBot/ChanOpCommands.pm @@ -8,9 +8,6 @@ package PBot::ChanOpCommands; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Carp (); sub new { @@ -62,7 +59,8 @@ sub ban_user { $length = 60 * 60; # one hour } - return "" if $target =~ /\Q$self->{pbot}->botnick\E/i; + my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick'); + return "" if $target =~ /\Q$botnick\E/i; $self->{pbot}->chanops->ban_user_timed($target, $from, $length); return "/msg $nick $target banned in $from for $length seconds"; diff --git a/PBot/ChanOps.pm b/PBot/ChanOps.pm index 9b57a09e..30a94a47 100644 --- a/PBot/ChanOps.pm +++ b/PBot/ChanOps.pm @@ -8,9 +8,6 @@ package PBot::ChanOps; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Time::HiRes qw(gettimeofday); sub new { @@ -34,7 +31,10 @@ sub initialize { } $self->{pbot} = $pbot; - $self->{unban_timeout} = PBot::DualIndexHashObject->new(pbot => $pbot, name => 'Unban Timeouts', filename => "$pbot->{data_dir}/unban_timeouts"); + + $self->{unban_timeout} = PBot::DualIndexHashObject->new(pbot => $pbot, name => 'Unban Timeouts', filename => $pbot->{registry}->get_value('general', 'data_dir') . '/unban_timeouts'); + $self->{unban_timeout}->load; + $self->{op_commands} = {}; $self->{is_opped} = {}; @@ -57,7 +57,7 @@ sub gain_ops { sub lose_ops { my $self = shift; my $channel = shift; - $self->{pbot}->conn->privmsg("chanserv", "op $channel -" . $self->{pbot}->botnick); + $self->{pbot}->conn->privmsg("chanserv", "op $channel -" . $self->{pbot}->{registry}->get_value('irc', 'botnick')); } sub add_op_command { @@ -68,6 +68,7 @@ sub add_op_command { sub perform_op_commands { my $self = shift; my $channel = shift; + my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick'); $self->{pbot}->logger->log("Performing op commands...\n"); while(my $command = shift @{ $self->{op_commands}->{$channel} }) { @@ -75,7 +76,7 @@ sub perform_op_commands { $self->{pbot}->conn->mode($1, $2); $self->{pbot}->logger->log(" executing mode $1 $2\n"); } elsif($command =~ /^kick (.*?) (.*?) (.*)/i) { - $self->{pbot}->conn->kick($1, $2, $3) unless $1 =~ /\Q$self->{pbot}->botnick\E/i; + $self->{pbot}->conn->kick($1, $2, $3) unless $1 =~ /\Q$botnick\E/i; $self->{pbot}->logger->log(" executing kick on $1 $2 $3\n"); } } diff --git a/PBot/Channels.pm b/PBot/Channels.pm index f1ca2e9d..97a87819 100644 --- a/PBot/Channels.pm +++ b/PBot/Channels.pm @@ -8,9 +8,6 @@ package PBot::Channels; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Carp (); use PBot::HashObject; @@ -29,17 +26,16 @@ sub new { sub initialize { my ($self, %conf) = @_; - my $pbot = delete $conf{pbot} // Carp::croak("Missing pbot reference to Channels"); - my $filename = delete $conf{filename}; + $self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to Channels"); - $self->{pbot} = $pbot; - $self->{channels} = PBot::HashObject->new(pbot => $pbot, name => 'Channels', filename => $filename); + $self->{channels} = PBot::HashObject->new(pbot => $self->{pbot}, name => 'Channels', filename => delete $conf{filename}); + $self->load_channels; - $pbot->commands->register(sub { $self->set(@_) }, "chanset", 40); - $pbot->commands->register(sub { $self->unset(@_) }, "chanunset", 40); - $pbot->commands->register(sub { $self->add(@_) }, "chanadd", 40); - $pbot->commands->register(sub { $self->remove(@_) }, "chanrem", 40); - $pbot->commands->register(sub { $self->list(@_) }, "chanlist", 10); + $self->{pbot}->commands->register(sub { $self->set(@_) }, "chanset", 40); + $self->{pbot}->commands->register(sub { $self->unset(@_) }, "chanunset", 40); + $self->{pbot}->commands->register(sub { $self->add(@_) }, "chanadd", 40); + $self->{pbot}->commands->register(sub { $self->remove(@_) }, "chanrem", 40); + $self->{pbot}->commands->register(sub { $self->list(@_) }, "chanlist", 10); } sub set { diff --git a/PBot/Commands.pm b/PBot/Commands.pm index 32144982..4d837978 100644 --- a/PBot/Commands.pm +++ b/PBot/Commands.pm @@ -13,9 +13,6 @@ use strict; use base 'PBot::Registerable'; -use vars qw($VERSION); -$VERSION = '1.0.0'; - use Carp (); sub new { diff --git a/PBot/DualIndexHashObject.pm b/PBot/DualIndexHashObject.pm index 1bb7fe3e..0ff3a42c 100644 --- a/PBot/DualIndexHashObject.pm +++ b/PBot/DualIndexHashObject.pm @@ -9,9 +9,6 @@ package PBot::DualIndexHashObject; use warnings; use strict; -use vars qw($VERSION); -$VERSION = "1.0"; - use Text::Levenshtein qw(fastdistance); use Carp (); @@ -30,18 +27,9 @@ sub new { sub initialize { my ($self, %conf) = @_; - my $name = delete $conf{name}; - if(not defined $name) { - $name = "dual index hash object"; - } - - my $filename = delete $conf{filename}; - if(not defined $filename) { - Carp::carp("Missing filename to DualIndexHashObject, will not be able to save to or load from file."); - } - - $self->{name} = $name; - $self->{filename} = $filename; + $self->{name} = delete $conf{name} // 'Dual Index hash object'; + $self->{filename} = delete $conf{filename} // Carp::carp("Missing filename to DualIndexHashObject, will not be able to save to or load from file."); + $self->{ignore_duplicates} = delete $conf{ignore_duplicates} // 0; $self->{hash} = {}; } @@ -50,7 +38,7 @@ sub load_hash_add { my ($self, $primary_index_key, $secondary_index_key, $hash, $i, $filename) = @_; if(defined $hash) { - if(exists $self->hash->{$primary_index_key}->{$secondary_index_key}) { + if(not $self->{ignore_duplicates} and exists $self->hash->{$primary_index_key}->{$secondary_index_key}) { if($i) { Carp::croak "Duplicate secondary_index_key '$secondary_index_key' found in $filename around line $i\n"; } else { @@ -67,10 +55,9 @@ sub load_hash_add { } sub load { - my $self = shift; - my $filename; + my ($self, $filename) = @_; - if(@_) { $filename = shift; } else { $filename = $self->filename; } + $filename = $self->filename if not defined $filename; if(not defined $filename) { Carp::carp "No $self->{name} filename specified -- skipping loading from file"; @@ -93,19 +80,13 @@ sub load { if($line =~ /^\[(.*)\]$/) { $primary_index_key = $1; - - if(exists $self->hash->{$primary_index_key} and $primary_index_key ne '.*') { - Carp::croak "Duplicate primary_index_key '$primary_index_key' at line $i of $filename\n"; - } - - $self->hash->{$primary_index_key} = {}; next; } if($line =~ /^<(.*)>$/) { $secondary_index_key = $1; - if(exists $self->hash->{$primary_index_key}->{$secondary_index_key}) { + if(not $self->{ignore_duplicates} and exists $self->hash->{$primary_index_key}->{$secondary_index_key}) { Carp::croak "Duplicate secondary_index_key '$secondary_index_key' at line $i of $filename\n"; } @@ -237,12 +218,12 @@ sub levenshtein_matches { } sub set { - my ($self, $primary_index_key, $secondary_index_key, $key, $value) = @_; + my ($self, $primary_index_key, $secondary_index_key, $key, $value, $dont_save) = @_; my $primary = $self->find_index($primary_index_key); if(not $primary) { - my $result = "No such $self->{name} object group '$primary_index_key'; similiar matches: "; + my $result = "No such $self->{name} object [$primary_index_key]; similiar matches: "; $result .= $self->levenshtein_matches($primary_index_key); return $result; } @@ -250,13 +231,13 @@ sub set { my $secondary = $self->find_index($primary, $secondary_index_key); if(not $secondary) { - my $result = "No such $self->{name} object '$secondary_index_key'; similiar matches: "; + my $result = "No such $self->{name} object [$primary_index_key] $secondary_index_key; similiar matches: "; $result .= $self->levenshtein_matches($primary, $secondary_index_key); return $result; } if(not defined $key) { - my $result = "[$self->{name}] (" . ($primary eq '.*' ? 'global' : $primary) . ") $secondary keys: "; + my $result = "[" . ($primary eq '.*' ? 'global' : $primary) . "] $secondary keys: "; my $comma = ''; foreach my $key (sort keys %{ $self->hash->{$primary}->{$secondary} }) { $result .= $comma . "$key => " . $self->hash->{$primary}->{$secondary}->{$key}; @@ -270,11 +251,11 @@ sub set { $value = $self->hash->{$primary}->{$secondary}->{$key}; } else { $self->hash->{$primary}->{$secondary}->{$key} = $value; - $self->save(); + $self->save unless $dont_save; } $primary = 'global' if $primary eq '.*'; - return "[$self->{name}] ($primary) $secondary: '$key' " . (defined $value ? "set to '$value'" : "is not set."); + return "[$primary] $secondary: '$key' " . (defined $value ? "set to '$value'" : "is not set."); } sub unset { diff --git a/PBot/FactoidCommands.pm b/PBot/FactoidCommands.pm index b79f2d61..ec148919 100644 --- a/PBot/FactoidCommands.pm +++ b/PBot/FactoidCommands.pm @@ -8,9 +8,6 @@ package PBot::FactoidCommands; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Carp (); use Time::Duration; use Time::HiRes qw(gettimeofday); @@ -87,7 +84,7 @@ sub call_factoid { my ($chan, $keyword, $args) = split / /, $arguments, 3; if(not defined $chan or not defined $keyword) { - return "Usage: !fact [arguments]"; + return "Usage: fact [arguments]"; } my ($channel, $trigger) = $self->{pbot}->factoids->find_factoid($chan, $keyword, $args, 1); @@ -105,7 +102,7 @@ sub factset { my ($channel, $trigger, $key, $value) = split / /, $arguments, 4 if defined $arguments; if(not defined $channel or not defined $trigger) { - return "Usage: factset [key ]" + return "Usage: factset [key [value]]"; } my $admininfo = $self->{pbot}->admins->loggedin($from, "$nick!$user\@$host"); @@ -194,13 +191,14 @@ sub factunset { sub list { my $self = shift; my ($from, $nick, $user, $host, $arguments) = @_; - my $botnick = $self->{pbot}->botnick; my $text; if(not defined $arguments) { return "/msg $nick Usage: list "; } + # TODO - update this to use new MessageHistory API +=cut if($arguments =~/^messages\s+(.*)$/) { my ($mask_search, $channel_search, $text_search) = split / /, $1; @@ -215,12 +213,12 @@ sub list { $nickserv = $self->{pbot}->antiflood->message_history->{$history_mask}->{nickserv_account} if exists $self->{pbot}->antiflood->message_history->{$history_mask}->{nickserv_account}; if($history_mask =~ m/$mask_search/i) { + my $bot_trigger = $self->{pbot}->{registry}->get_value('general', 'trigger'); foreach my $history_channel (keys %{ $self->{pbot}->antiflood->message_history->{$history_mask}->{channels} }) { if($history_channel =~ m/$channel_search/i) { my @messages = @{ $self->{pbot}->antiflood->message_history->{$history_mask}->{channels}->{$history_channel}{messages} }; - for(my $i = 0; $i <= $#messages; $i++) { - next if $messages[$i]->{msg} =~ /^\Q$self->{pbot}->{trigger}\E?login/; # don't reveal login passwords + next if $messages[$i]->{msg} =~ /^\Q$bot_trigger\E?login/; # don't reveal login passwords print "$history_mask, $history_channel\n"; print "joinwatch: ", $self->{pbot}->antiflood->message_history->{$history_mask}->{channels}->{$history_channel}{join_watch}, "\n"; @@ -264,6 +262,7 @@ sub list { $self->{pbot}->logger->log($text); return "Messages:\n\n$text"; } +=cut if($arguments =~ /^modules$/i) { $from = '.*' if not defined $from or $from !~ /^#/; diff --git a/PBot/FactoidModuleLauncher.pm b/PBot/FactoidModuleLauncher.pm index 07044975..225344f5 100644 --- a/PBot/FactoidModuleLauncher.pm +++ b/PBot/FactoidModuleLauncher.pm @@ -8,9 +8,6 @@ package PBot::FactoidModuleLauncher; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use POSIX qw(WNOHANG); # for children process reaping use Carp (); use Text::Balanced qw(extract_delimited); @@ -55,7 +52,7 @@ sub execute_module { } my $module = $self->{pbot}->factoids->factoids->hash->{$channel}->{$trigger}->{action}; - my $module_dir = $self->{pbot}->module_dir; + my $module_dir = $self->{pbot}->{registry}->get_value('general', 'module_dir'); $self->{pbot}->logger->log("(" . (defined $from ? $from : "(undef)") . "): $nick!$user\@$host: Executing module $module $arguments\n"); @@ -187,8 +184,8 @@ sub module_pipe_reader { my ($self, $buf) = @_; my ($channel, $text) = split / /, $buf, 2; return if not defined $text or not length $text; - $text = $self->{pbot}->interpreter->truncate_result($channel, $self->{pbot}->{botnick}, 'undef', $text, $text, 0); - $self->{pbot}->antiflood->check_flood($channel, $self->{pbot}->{botnick}, $self->{pbot}->{username}, 'localhost', $text, 0, 0, 0); + $text = $self->{pbot}->interpreter->truncate_result($channel, $self->{pbot}->{registry}->get_value('irc', 'botnick'), 'undef', $text, $text, 0); + $self->{pbot}->antiflood->check_flood($channel, $self->{pbot}->{registry}->get_value('irc', 'botnick'), $self->{pbot}->{registry}->get_value('irc', 'username'), 'localhost', $text, 0, 0, 0); } 1; diff --git a/PBot/Factoids.pm b/PBot/Factoids.pm index 8d6a8e1d..055ea5cf 100644 --- a/PBot/Factoids.pm +++ b/PBot/Factoids.pm @@ -8,14 +8,12 @@ package PBot::Factoids; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use HTML::Entities; use Time::HiRes qw(gettimeofday); use Carp (); use POSIX qw(strftime); +use PBot::PBot qw($VERSION); use PBot::FactoidModuleLauncher; use PBot::DualIndexHashObject; @@ -48,6 +46,9 @@ sub initialize { $self->{factoidmodulelauncher} = PBot::FactoidModuleLauncher->new(pbot => $pbot); $self->{pbot}->{atexit}->register(sub { $self->save_factoids; return; }); + + $self->load_factoids; + $self->add_factoid('text', '.*', $self->{pbot}->{registry}->get_value('irc', 'botnick'), 'version', "/say $VERSION", 1); } sub load_factoids { @@ -80,7 +81,7 @@ sub save_factoids { sub add_factoid { my $self = shift; - my ($type, $channel, $owner, $trigger, $action) = @_; + my ($type, $channel, $owner, $trigger, $action, $dont_save) = @_; $type = lc $type; $channel = lc $channel; @@ -94,7 +95,7 @@ sub add_factoid { $self->factoids->hash->{$channel}->{$trigger}->{ref_user} = "nobody"; $self->factoids->hash->{$channel}->{$trigger}->{rate_limit} = 15; - $self->save_factoids; + $self->save_factoids unless $dont_save; } sub remove_factoid { @@ -104,6 +105,11 @@ sub remove_factoid { $channel = lc $channel; delete $self->factoids->hash->{$channel}->{$trigger}; + + if(not scalar keys $self->factoids->hash->{$channel}) { + delete $self->factoids->hash->{$channel}; + } + $self->save_factoids; } @@ -449,7 +455,7 @@ sub interpreter { if(defined $tonick) { # !tell foo about bar $self->{pbot}->logger->log("($from): $nick!$user\@$host) sent to $tonick\n"); - my $botnick = $self->{pbot}->botnick; + my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick'); # get rid of original caller's nick $result =~ s/^\/([^ ]+) \Q$nick\E:\s+/\/$1 /; diff --git a/PBot/HashObject.pm b/PBot/HashObject.pm index a978c35a..20d12309 100644 --- a/PBot/HashObject.pm +++ b/PBot/HashObject.pm @@ -9,9 +9,6 @@ package PBot::HashObject; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Text::Levenshtein qw(fastdistance); use Carp (); diff --git a/PBot/IRCHandlers.pm b/PBot/IRCHandlers.pm index 3916f225..e6159c94 100644 --- a/PBot/IRCHandlers.pm +++ b/PBot/IRCHandlers.pm @@ -8,9 +8,6 @@ package PBot::IRCHandlers; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Carp(); use Time::HiRes qw(gettimeofday); @@ -70,15 +67,16 @@ sub on_public { my $host = $event->host; my $text = $event->{args}[0]; - $self->pbot->interpreter->process_line($from, $nick, $user, $host, $text); + $self->{pbot}->interpreter->process_line($from, $nick, $user, $host, $text); } sub on_msg { my ($self, $conn, $event) = @_; my ($nick, $host) = ($event->nick, $event->host); my $text = $event->{args}[0]; + my $bot_trigger = $self->{pbot}->{registry}->get_value('general', 'trigger'); - $text =~ s/^\Q$self->{pbot}->{trigger}\E?(.*)/$self->{pbot}->{trigger}$1/; + $text =~ s/^\Q$bot_trigger\E?(.*)/$bot_trigger$1/; $event->{to}[0] = $nick; $event->{args}[0] = $text; $self->on_public($conn, $event); @@ -93,7 +91,7 @@ sub on_notice { if($nick eq "NickServ" && $text =~ m/This nickname is registered/) { $self->{pbot}->logger->log("Identifying with NickServ . . .\n"); - $conn->privmsg("nickserv", "identify " . $self->pbot->identify_password); + $conn->privmsg("nickserv", "identify " . $self->{pbot}->{registry}->get_value('irc', 'identify_password')); } if($nick eq "NickServ" && $text =~ m/You are now identified/) { @@ -143,7 +141,7 @@ sub on_mode { $self->{pbot}->bantracker->track_mode("$nick!$user\@$host", $mode, $target, $channel); } - if(defined $target && $target eq $self->{pbot}->botnick) { # bot targeted + if(defined $target && $target eq $self->{pbot}->{registry}->get_value('irc', 'botnick')) { # bot targeted if($mode eq "+o") { $self->{pbot}->logger->log("$nick opped me in $channel\n"); $self->{pbot}->chanops->{is_opped}->{$channel}{timeout} = gettimeofday + 300; # 5 minutes @@ -165,7 +163,7 @@ sub on_mode { $self->{pbot}->chanops->{unban_timeout}->save; } } - elsif($mode eq "+e" && $channel eq $self->{pbot}->botnick) { + elsif($mode eq "+e" && $channel eq $self->{pbot}->{registry}->get_value('irc', 'botnick')) { foreach my $chan (keys %{ $self->{pbot}->channels->channels->hash }) { if($self->channels->channels->hash->{$chan}{enabled}) { $self->{pbot}->logger->log("Joining channel: $chan\n"); @@ -185,7 +183,7 @@ sub on_join { 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}); - $self->{pbot}->antiflood->check_flood($channel, $nick, $user, $host, "JOIN", 4, 60 * 30, $self->{pbot}->{messagehistory}->{MSG_JOIN}); + $self->{pbot}->antiflood->check_flood($channel, $nick, $user, $host, "JOIN", $self->{pbot}->{registry}->get_value('antiflood', 'max_join_flood'), 60 * 30, $self->{pbot}->{messagehistory}->{MSG_JOIN}); } sub on_kick { @@ -203,7 +201,7 @@ sub on_kick { my $text = "KICKED by $nick!$user\@$host ($reason)"; $self->{pbot}->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $channel, $text, $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}); - $self->{pbot}->antiflood->check_flood($channel, $target_nick, $target_user, $target_host, $text, 4, 60 * 30, $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}); + $self->{pbot}->antiflood->check_flood($channel, $target_nick, $target_user, $target_host, $text, $self->{pbot}->{registry}->get_value('antiflood', 'max_join_flood'), 60 * 30, $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}); } } @@ -227,7 +225,7 @@ sub on_departure { $self->{pbot}->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $channel, $text, $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}); } - $self->{pbot}->antiflood->check_flood($channel, $nick, $user, $host, $text, 4, 60 * 30, $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}); + $self->{pbot}->antiflood->check_flood($channel, $nick, $user, $host, $text, $self->{pbot}->{registry}->get_value('antiflood', 'max_join_flood'), 60 * 30, $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}); my $admin = $self->{pbot}->admins->find_admin($channel, "$nick!$user\@$host"); if(defined $admin and $admin->{loggedin}) { @@ -255,12 +253,7 @@ sub on_nickchange { $self->{pbot}->{messagehistory}->{database}->devalidate_all_channels($newnick_account); $self->{pbot}->{messagehistory}->{database}->update_hostmask_data($newnick_account, { last_seen => scalar gettimeofday }); - $self->{pbot}->antiflood->check_flood("$nick!$user\@$host", $nick, $user, $host, "NICKCHANGE $newnick", 3, 60 * 30, $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE}); -} - -sub pbot { - my $self = shift; - return $self->{pbot}; + $self->{pbot}->antiflood->check_flood("$nick!$user\@$host", $nick, $user, $host, "NICKCHANGE $newnick", $self->{pbot}->{registry}->get_value('antiflood', 'max_nick_flood'), 60 * 30, $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE}); } 1; diff --git a/PBot/IgnoreList.pm b/PBot/IgnoreList.pm index cd587b27..4c693857 100644 --- a/PBot/IgnoreList.pm +++ b/PBot/IgnoreList.pm @@ -8,9 +8,6 @@ package PBot::IgnoreList; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Time::HiRes qw(gettimeofday); sub new { @@ -28,20 +25,16 @@ sub new { sub initialize { my ($self, %conf) = @_; - my $pbot = delete $conf{pbot}; - if(not defined $pbot) { - Carp::croak("Missing pbot reference to Channels"); - } + $self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to Channels"); + $self->{filename} = delete $conf{filename}; - my $filename = delete $conf{filename}; - - $self->{pbot} = $pbot; $self->{ignore_list} = {}; $self->{ignore_flood_counter} = {}; $self->{last_timestamp} = {}; - $self->{filename} = $filename; - $pbot->timer->register(sub { $self->check_ignore_timeouts }, 10); + $self->load_ignores; + + $self->{pbot}->timer->register(sub { $self->check_ignore_timeouts }, 10); } sub add { diff --git a/PBot/IgnoreListCommands.pm b/PBot/IgnoreListCommands.pm index 35a3d40e..7180533f 100644 --- a/PBot/IgnoreListCommands.pm +++ b/PBot/IgnoreListCommands.pm @@ -8,9 +8,6 @@ package PBot::IgnoreListCommands; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Time::HiRes qw(gettimeofday); use Carp (); diff --git a/PBot/Interpreter.pm b/PBot/Interpreter.pm index 46ec7c7e..1aff6b8a 100644 --- a/PBot/Interpreter.pm +++ b/PBot/Interpreter.pm @@ -13,9 +13,6 @@ use base 'PBot::Registerable'; use LWP::UserAgent; use Carp (); -use vars qw($VERSION); -$VERSION = '1.0.0'; - sub new { if(ref($_[1]) eq 'HASH') { Carp::croak("Options to Interpreter should be key/value pairs, not hash reference"); @@ -91,7 +88,7 @@ sub process_line { my $has_url; my $has_code; my $nick_override; - my $mynick = $self->pbot->botnick; + my $mynick = $self->{pbot}->{registry}->get_value('irc', 'botnick'); $from = lc $from if defined $from; @@ -100,7 +97,7 @@ sub process_line { my $message_account = $pbot->{messagehistory}->get_message_account($nick, $user, $host); $pbot->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $from, $text, $pbot->{messagehistory}->{MSG_CHAT}); - $pbot->antiflood->check_flood($from, $nick, $user, $host, $text, $pbot->{MAX_FLOOD_MESSAGES}, 10, $pbot->{messagehistory}->{MSG_CHAT}) if defined $from; + $pbot->antiflood->check_flood($from, $nick, $user, $host, $text, $pbot->{registry}->get_value('antiflood', 'max_chat_flood'), 10, $pbot->{messagehistory}->{MSG_CHAT}) if defined $from; $text =~ s/^\s+//; $text =~ s/\s+$//; @@ -109,10 +106,12 @@ sub process_line { my $cmd_text = $text; $cmd_text =~ s/^\/me\s+//; - if($cmd_text =~ /^$pbot->{trigger}?\s*{\s*(.*)\s*}\s*$/) { + my $bot_trigger = $pbot->{registry}->get_value('general', 'trigger'); + + if($cmd_text =~ /^$bot_trigger?\s*{\s*(.*)\s*}\s*$/) { $has_code = $1 if length $1; $preserve_whitespace = 1; - } elsif($cmd_text =~ /^\Q$pbot->{trigger}\E(.*)$/) { + } elsif($cmd_text =~ /^\Q$bot_trigger\E(.*)$/) { $command = $1; } elsif($cmd_text =~ /^.?$mynick.?\s+(.*?)$/i) { $command = $1; @@ -147,8 +146,9 @@ sub process_line { sub truncate_result { my ($self, $from, $nick, $text, $original_result, $result, $paste) = @_; + my $max_msg_len = $self->{pbot}->{registry}->get_value('irc', 'max_msg_len'); - if(length $result > $self->{pbot}->max_msg_len) { + if(length $result > $max_msg_len) { my $link; if($paste) { $link = paste_sprunge("[" . (defined $from ? $from : "stdin") . "] <$nick> $text\n\n$original_result"); @@ -159,7 +159,7 @@ sub truncate_result { my $trunc = "... [truncated; see $link for full text.]"; $self->{pbot}->logger->log("Message truncated -- pasted to $link\n") if $paste; - my $trunc_len = length $result < $self->{pbot}->max_msg_len ? length $result : $self->{pbot}->max_msg_len; + my $trunc_len = length $result < $max_msg_len ? length $result : $max_msg_len; $result = substr($result, 0, $trunc_len); substr($result, $trunc_len - length $trunc) = $trunc; } @@ -169,7 +169,7 @@ sub truncate_result { sub handle_result { my ($self, $from, $nick, $user, $host, $text, $command, $result, $checkflood, $preserve_whitespace) = @_; - my ($pbot, $mynick) = ($self->{pbot}, $self->{pbot}->{botnick}); + my ($pbot, $mynick) = ($self->{pbot}, $self->{pbot}->{registry}->get_value('irc', 'botnick')); if(not defined $result or length $result == 0) { return; @@ -194,10 +194,10 @@ sub handle_result { if($result =~ s/^\/say\s+//i) { $pbot->conn->privmsg($from, $result) if defined $from && $from !~ /\Q$mynick\E/i; - $pbot->antiflood->check_flood($from, $pbot->{botnick}, $pbot->{username}, 'localhost', $result, 0, 0, 0) if $checkflood; + $pbot->antiflood->check_flood($from, $mynick, $pbot->{registry}->get_value('irc', 'username'), 'localhost', $result, 0, 0, 0) if $checkflood; } elsif($result =~ s/^\/me\s+//i) { $pbot->conn->me($from, $result) if defined $from && $from !~ /\Q$mynick\E/i; - $pbot->antiflood->check_flood($from, $pbot->{botnick}, $pbot->{username}, 'localhost', '/me ' . $result, 0, 0, 0) if $checkflood; + $pbot->antiflood->check_flood($from, $mynick, $pbot->{registry}->get_value('irc', 'username'), 'localhost', '/me ' . $result, 0, 0, 0) if $checkflood; } elsif($result =~ s/^\/msg\s+([^\s]+)\s+//i) { my $to = $1; if($to =~ /,/) { @@ -208,15 +208,15 @@ sub handle_result { } elsif($result =~ s/^\/me\s+//i) { $pbot->conn->me($to, $result) if $to !~ /\Q$mynick\E/i; - $pbot->antiflood->check_flood($to, $pbot->{botnick}, $pbot->{username}, 'localhost', '/me ' . $result, 0, 0, 0) if $checkflood; + $pbot->antiflood->check_flood($to, $mynick, $pbot->{registry}->get_value('irc', 'username'), 'localhost', '/me ' . $result, 0, 0, 0) if $checkflood; } else { $result =~ s/^\/say\s+//i; $pbot->conn->privmsg($to, $result) if $to !~ /\Q$mynick\E/i; - $pbot->antiflood->check_flood($to, $pbot->{botnick}, $pbot->{username}, 'localhost', $result, 0, 0, 0) if $checkflood; + $pbot->antiflood->check_flood($to, $mynick, $pbot->{registry}->get_value('irc', 'username'), 'localhost', $result, 0, 0, 0) if $checkflood; } } else { $pbot->conn->privmsg($from, $result) if defined $from && $from !~ /\Q$mynick\E/i; - $pbot->antiflood->check_flood($from, $pbot->{botnick}, $pbot->{username}, 'localhost', $result, 0, 0, 0) if $checkflood; + $pbot->antiflood->check_flood($from, $mynick, $pbot->{registry}->get_value('irc', 'username'), 'localhost', $result, 0, 0, 0) if $checkflood; } $pbot->logger->log("---------------------------------------------\n"); } diff --git a/PBot/LagChecker.pm b/PBot/LagChecker.pm index 83063c56..1a9c8ac5 100644 --- a/PBot/LagChecker.pm +++ b/PBot/LagChecker.pm @@ -11,9 +11,6 @@ use strict; use feature 'switch'; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use Time::HiRes qw(gettimeofday tv_interval); use Time::Duration; use Carp (); diff --git a/PBot/Logger.pm b/PBot/Logger.pm index ac0f2c29..83fd7a33 100644 --- a/PBot/Logger.pm +++ b/PBot/Logger.pm @@ -3,9 +3,6 @@ package PBot::Logger; use warnings; use strict; -use vars qw($VERSION); -$VERSION = '1.0.0'; - use Carp (); sub new { diff --git a/PBot/MessageHistory.pm b/PBot/MessageHistory.pm index 0c91f2b9..f9424af3 100644 --- a/PBot/MessageHistory.pm +++ b/PBot/MessageHistory.pm @@ -33,7 +33,7 @@ sub new { sub initialize { my ($self, %conf) = @_; $self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__); - $self->{filename} = delete $conf{filename} // $self->{pbot}->{data_dir} . '/message_history.sqlite3'; + $self->{filename} = delete $conf{filename} // $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/message_history.sqlite3'; $self->{database} = PBot::MessageHistory_SQLite->new(pbot => $self->{pbot}, filename => $self->{filename}); $self->{database}->begin(); diff --git a/PBot/MessageHistory_SQLite.pm b/PBot/MessageHistory_SQLite.pm index 40050a1d..1db96891 100644 --- a/PBot/MessageHistory_SQLite.pm +++ b/PBot/MessageHistory_SQLite.pm @@ -27,7 +27,7 @@ sub initialize { my ($self, %conf) = @_; $self->{pbot} = delete $conf{pbot} // Carp::croak("Missing pbot reference in " . __FILE__); - $self->{filename} = delete $conf{filename} // $self->{pbot}->{data_dir} . '/message_history.sqlite3'; + $self->{filename} = delete $conf{filename} // $self->{pbot}->{registry}->get_value('general', 'data_dir') . '/message_history.sqlite3'; $self->{pbot}->timer->register(sub { $self->commit_message_history }, 5); $self->{new_entries} = 0; @@ -433,8 +433,10 @@ sub recall_message_by_count { $self->{pbot}->logger->log($@) if $@; if(defined $ignore_command) { + my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick'); + my $bot_trigger = $self->{pbot}->{registry}->get_value('general', 'trigger'); foreach my $message (@$messages) { - next if $message->{msg} =~ m/^$self->{pbot}->{botnick}. $ignore_command/ or $message->{msg} =~ m/^$self->{pbot}->{trigger}$ignore_command/; + next if $message->{msg} =~ m/^$botnick. $ignore_command/ or $message->{msg} =~ m/^$bot_trigger$ignore_command/; return $message; } return undef; @@ -474,8 +476,10 @@ sub recall_message_by_text { $self->{pbot}->logger->log($@) if $@; if(defined $ignore_command) { + my $bot_trigger = $self->{pbot}->{registry}->get_value('general', 'trigger'); + my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick'); foreach my $message (@$messages) { - next if $message->{msg} =~ m/^$self->{pbot}->{botnick}. $ignore_command/ or $message->{msg} =~ m/^$self->{pbot}->{trigger}$ignore_command/; + next if $message->{msg} =~ m/^$botnick. $ignore_command/ or $message->{msg} =~ m/^$bot_trigger$ignore_command/; return $message; } return undef; diff --git a/PBot/PBot.pm b/PBot/PBot.pm index 4b88a585..fecb0eec 100644 --- a/PBot/PBot.pm +++ b/PBot/PBot.pm @@ -12,8 +12,14 @@ use warnings; use PBot::VERSION; -use vars qw($VERSION); -$VERSION = PBot::VERSION::BUILD_NAME . " revision " . PBot::VERSION::BUILD_REVISION . " " . PBot::VERSION::BUILD_DATE; +BEGIN { + use Exporter; + our @ISA = 'Exporter'; + our @EXPORT = qw($VERSION); + + our $VERSION = PBot::VERSION::BUILD_NAME . " revision " . PBot::VERSION::BUILD_REVISION . " " . PBot::VERSION::BUILD_DATE; + print "PBot version $VERSION\n"; +} # unbuffer stdout STDOUT->autoflush(1); @@ -21,6 +27,8 @@ STDOUT->autoflush(1); use Carp (); use PBot::Logger; +use PBot::Registry; + use PBot::SelectHandler; use PBot::StdinReader; @@ -69,73 +77,70 @@ sub new { sub initialize { my ($self, %conf) = @_; - my $log_file = delete $conf{log_file}; + # logger created first to allow other modules to log things + $self->{logger} = PBot::Logger->new(log_file => delete $conf{log_file}); - $self->{config_dir} = delete $conf{config_dir} // "$ENV{HOME}/pbot/config"; - $self->{data_dir} = delete $conf{data_dir} // "$ENV{HOME}/pbot/data"; - $self->{module_dir} = delete $conf{module_dir} // "$ENV{HOME}/pbot/modules"; + $self->{atexit} = PBot::Registerable->new(); + $self->{timer} = PBot::Timer->new(timeout => 10); + $self->{commands} = PBot::Commands->new(pbot => $self); - $self->{ircserver} = delete $conf{ircserver} // "irc.freenode.net"; - $self->{port} = delete $conf{port} // 6667; - $self->{SSL} = delete $conf{SSL} // 0; - $self->{SSL_ca_file} = delete $conf{SSL_ca_file} // undef; - $self->{SSL_ca_path} = delete $conf{SSL_ca_path} // undef; - $self->{botnick} = delete $conf{botnick} // "pbot3"; - $self->{username} = delete $conf{username} // "pbot3"; - $self->{ircname} = delete $conf{ircname} // "http://code.google.com/p/pbot2-pl/"; - $self->{identify_password} = delete $conf{identify_password} // ""; + my $config_dir = delete $conf{config_dir} // "$ENV{HOME}/pbot/config"; - $self->{max_msg_len} = delete $conf{max_msg_len} // 425; - $self->{MAX_FLOOD_MESSAGES} = delete $conf{MAX_FLOOD_MESSAGES} // 4; - $self->{MAX_NICK_MESSAGES} = delete $conf{MAX_NICK_MESSAGES} // 32; + # registry created, but not yet loaded, to allow modules to create default values and triggers + $self->{registry} = PBot::Registry->new(pbot => $self, filename => delete $conf{registry_file} // "$config_dir/registry"); - $self->{trigger} = delete $conf{trigger} // '!'; + $self->{registry}->add_default('text', 'general', 'config_dir', $config_dir); + $self->{registry}->add_default('text', 'general', 'data_dir', delete $conf{data_dir} // "$ENV{HOME}/pbot/data"); + $self->{registry}->add_default('text', 'general', 'module_dir', delete $conf{module_dir} // "$ENV{HOME}/pbot/modules"); + $self->{registry}->add_default('text', 'general', 'trigger', delete $conf{trigger} // '!'); - my $messagehistory_file = delete $conf{message_history_file}; - my $channels_file = delete $conf{channels_file}; - my $admins_file = delete $conf{admins_file}; - my $ignorelist_file = delete $conf{ignorelist_file}; + $self->{registry}->add_default('text', 'irc', 'max_msg_len', delete $conf{max_msg_len} // 425); + $self->{registry}->add_default('text', 'irc', 'ircserver', delete $conf{ircserver} // "irc.freenode.net"); + $self->{registry}->add_default('text', 'irc', 'port', delete $conf{port} // 6667); + $self->{registry}->add_default('text', 'irc', 'SSL', delete $conf{SSL} // 0); + $self->{registry}->add_default('text', 'irc', 'SSL_ca_file', delete $conf{SSL_ca_file} // 'none'); + $self->{registry}->set('irc', 'SSL_ca_file', 'private', 1); + $self->{registry}->add_default('text', 'irc', 'SSL_ca_path', delete $conf{SSL_ca_path} // 'none'); + $self->{registry}->set('irc', 'SSL_ca_path', 'private', 1); + $self->{registry}->add_default('text', 'irc', 'botnick', delete $conf{botnick} // "pbot3"); + $self->{registry}->add_default('text', 'irc', 'username', delete $conf{username} // "pbot3"); + $self->{registry}->add_default('text', 'irc', 'ircname', delete $conf{ircname} // "http://code.google.com/p/pbot2-pl/"); + $self->{registry}->add_default('text', 'irc', 'identify_password', delete $conf{identify_password} // ""); + $self->{registry}->set('irc', 'identify_password', 'private', 1); - my $factoids_file = delete $conf{factoids_file}; - my $export_factoids_path = delete $conf{export_factoids_path}; - my $export_factoids_site = delete $conf{export_factoids_site}; + $self->{registry}->add_trigger('irc', 'botnick', sub { $self->change_botnick_trigger(@_) }); - my $quotegrabs_file = delete $conf{quotegrabs_file}; - my $export_quotegrabs_path = delete $conf{export_quotegrabs_path}; - my $export_quotegrabs_site = delete $conf{export_quotegrabs_site}; + $self->{registry}->add_default('text', 'antiflood', 'max_join_flood', delete $conf{max_join_flood} // 4); + $self->{registry}->add_default('text', 'antiflood', 'max_chat_flood', delete $conf{max_chat_flood} // 4); + $self->{registry}->add_default('text', 'antiflood', 'max_enter_flood', delete $conf{max_enter_flood} // 4); + $self->{registry}->add_default('text', 'antiflood', 'max_nick_flood', delete $conf{max_nick_flood} // 3); - $self->{logger} = PBot::Logger->new(log_file => $log_file); - $self->{commands} = PBot::Commands->new(pbot => $self); - $self->{timer} = PBot::Timer->new(timeout => 10); - - $self->{atexit} = PBot::Registerable->new(); + $self->{registry}->add_default('text', 'antiflood', 'enter_abuse_max_lines', delete $conf{enter_abuse_max_lines} // 4); + $self->{registry}->add_default('text', 'antiflood', 'enter_abuse_max_seconds', delete $conf{enter_abuse_max_seconds} // 20); + $self->{registry}->add_default('text', 'antiflood', 'enter_abuse_max_offenses', delete $conf{enter_abuse_max_offenses} // 3); + $self->{registry}->add_default('text', 'messagehistory', 'max_messages', delete $conf{max_messages} // 32); + $self->{select_handler} = PBot::SelectHandler->new(pbot => $self); $self->{stdin_reader} = PBot::StdinReader->new(pbot => $self); - $self->{admins} = PBot::BotAdmins->new(pbot => $self, filename => $admins_file); + $self->{admins} = PBot::BotAdmins->new(pbot => $self, filename => delete $conf{admins_file}); $self->admins->load_admins(); - $self->admins->add_admin($self->{botnick}, '.*', "$self->{botnick}!stdin\@localhost", 60, 'admin'); - $self->admins->login($self->{botnick}, "$self->{botnick}!stdin\@localhost", 'admin'); $self->{factoids} = PBot::Factoids->new( pbot => $self, - filename => $factoids_file, - export_path => $export_factoids_path, - export_site => $export_factoids_site, + filename => delete $conf{factoids_file}, + export_path => delete $conf{export_factoids_path}, + export_site => delete $conf{export_factoids_site}, ); - $self->factoids->load_factoids() if defined $factoids_file; - $self->factoids->add_factoid('text', '.*', $self->{botnick}, 'version', "/say $VERSION"); - $self->{bantracker} = PBot::BanTracker->new(pbot => $self); $self->{lagchecker} = PBot::LagChecker->new(pbot => $self); - $self->{messagehistory} = PBot::MessageHistory->new(pbot => $self, filename => $messagehistory_file); + $self->{messagehistory} = PBot::MessageHistory->new(pbot => $self, filename => delete $conf{messagehistory_file}); $self->{antiflood} = PBot::AntiFlood->new(pbot => $self); - $self->{ignorelist} = PBot::IgnoreList->new(pbot => $self, filename => $ignorelist_file); - $self->{ignorelist}->load_ignores() if defined $ignorelist_file; + $self->{ignorelist} = PBot::IgnoreList->new(pbot => $self, filename => delete $conf{ignorelist_file}); $self->interpreter(PBot::Interpreter->new(pbot => $self)); $self->interpreter->register(sub { return $self->commands->interpreter(@_); }); @@ -148,21 +153,27 @@ sub initialize { $self->{irc} = PBot::IRC->new(); $self->{irchandlers} = PBot::IRCHandlers->new(pbot => $self); - $self->{channels} = PBot::Channels->new(pbot => $self, filename => $channels_file); - $self->channels->load_channels() if defined $channels_file; + $self->{channels} = PBot::Channels->new(pbot => $self, filename => delete $conf{channels_file}); $self->{chanops} = PBot::ChanOps->new(pbot => $self); $self->{chanopcmds} = PBot::ChanOpCommands->new(pbot => $self); - $self->{chanops}->{unban_timeout}->load; - $self->{quotegrabs} = PBot::Quotegrabs->new( pbot => $self, - filename => $quotegrabs_file, - export_path => $export_quotegrabs_path, - export_site => $export_quotegrabs_site, + filename => delete $conf{quotegrabs_file}, + export_path => delete $conf{export_quotegrabs_path}, + export_site => delete $conf{export_quotegrabs_site}, ); + # load registry entries from file to overwrite defaults + $self->{registry}->load; + + # create implicit bot-admin account for bot + my $botnick = $self->{registry}->get_value('irc', 'botnick'); + $self->admins->add_admin($botnick, '.*', "$botnick!stdin\@localhost", 60, 'admin', 1); + $self->admins->login($botnick, "$botnick!stdin\@localhost", 'admin'); + + # start timer $self->timer->start(); } @@ -171,47 +182,47 @@ sub initialize { sub connect { my ($self, $server) = @_; - $server = $self->ircserver if not defined $server; - if($self->{connected}) { # TODO: disconnect, clean-up, etc } + $server = $self->{registry}->get_value('irc', 'ircserver') if not defined $server; + $self->logger->log("Connecting to $server ...\n"); $self->conn($self->irc->newconn( - Nick => $self->{botnick}, - Username => $self->{username}, - Ircname => $self->{ircname}, + 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->{SSL}, - SSL_ca_file => $self->{SSL_ca_file}, - SSL_ca_path => $self->{SSL_ca_path}, - Port => $self->{port})) + 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"; $self->{connected} = 1; #set up default handlers for the IRC engine - $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('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([ 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('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(@_) }); # freenode quietlist $self->conn->add_handler(728 , sub { $self->bantracker->on_quietlist_entry(@_) }); - $self->conn->add_handler('endofnames' , sub { $self->bantracker->get_banlist(@_) }); } #main loop @@ -228,7 +239,7 @@ sub do_one_loop { sub start { my $self = shift; - if(not defined $self->{connected} or $self->{connected} == 0) { + if(not $self->{connected}) { $self->connect(); } @@ -247,6 +258,14 @@ sub atexit { $self->{atexit}->execute_all; } +sub change_botnick_trigger { + my ($self, $section, $item, $newvalue) = @_; + + if($self->{connected}) { + $self->conn->nick($newvalue); + } +} + #----------------------------------------------------------------------------------- # Getters/Setters #----------------------------------------------------------------------------------- @@ -310,30 +329,6 @@ sub commands { return $self->{commands}; } -sub botnick { - my $self = shift; - if(@_) { $self->{botnick} = shift; } - return $self->{botnick}; -} - -sub identify_password { - my $self = shift; - if(@_) { $self->{identify_password} = shift; } - return $self->{identify_password}; -} - -sub max_msg_len { - my $self = shift; - if(@_) { $self->{max_msg_len} = shift; } - return $self->{max_msg_len}; -} - -sub module_dir { - my $self = shift; - if(@_) { $self->{module_dir} = shift; } - return $self->{module_dir}; -} - sub ignorelist { my $self = shift; if(@_) { $self->{ignorelist} = shift; } @@ -370,10 +365,4 @@ sub chanops { return $self->{chanops}; } -sub ircserver { - my $self = shift; - if(@_) { $self->{ircserver} = shift; } - return $self->{ircserver}; -} - 1; diff --git a/PBot/Quotegrabs.pm b/PBot/Quotegrabs.pm index e36e9fe0..e0ffa799 100644 --- a/PBot/Quotegrabs.pm +++ b/PBot/Quotegrabs.pm @@ -8,9 +8,6 @@ package PBot::Quotegrabs; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use HTML::Entities; use Time::Duration; use Time::HiRes qw(gettimeofday); diff --git a/PBot/Quotegrabs_Hashtable.pm b/PBot/Quotegrabs_Hashtable.pm index 889f26e2..9b97783b 100644 --- a/PBot/Quotegrabs_Hashtable.pm +++ b/PBot/Quotegrabs_Hashtable.pm @@ -8,9 +8,6 @@ package PBot::Quotegrabs_Hashtable; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use HTML::Entities; use Time::Duration; use Time::HiRes qw(gettimeofday); diff --git a/PBot/Quotegrabs_SQLite.pm b/PBot/Quotegrabs_SQLite.pm index 7abf83df..4f4b596d 100644 --- a/PBot/Quotegrabs_SQLite.pm +++ b/PBot/Quotegrabs_SQLite.pm @@ -8,9 +8,6 @@ package PBot::Quotegrabs_SQLite; use warnings; use strict; -use vars qw($VERSION); -$VERSION = $PBot::PBot::VERSION; - use DBI; use Carp qw(shortmess); diff --git a/PBot/Registerable.pm b/PBot/Registerable.pm index 7e8903b4..87d7f0ab 100644 --- a/PBot/Registerable.pm +++ b/PBot/Registerable.pm @@ -8,9 +8,6 @@ package PBot::Registerable; use warnings; use strict; -use vars qw($VERSION); -$VERSION = '1.0.0'; - use Carp (); sub new { diff --git a/PBot/Registry.pm b/PBot/Registry.pm new file mode 100644 index 00000000..4da64024 --- /dev/null +++ b/PBot/Registry.pm @@ -0,0 +1,156 @@ +# File: Registry.pm +# Author: pragma_ +# +# Purpose: Provides a centralized registry of configuration settings that can +# easily be examined and updated via set/unset commands without restarting. + +package PBot::Registry; + +use warnings; +use strict; + +use Time::HiRes qw(gettimeofday); +use Carp (); + +use PBot::DualIndexHashObject; +use PBot::RegistryCommands; + +sub new { + if(ref($_[1]) eq 'HASH') { + Carp::croak("Options to " . __FILE__ . " should be item/value pairs, not hash reference"); + } + + 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 to " . __FILE__); + my $filename = delete $conf{filename}; + + $self->{registry} = PBot::DualIndexHashObject->new(name => 'Registry', filename => $filename, ignore_duplicates => 1); + $self->{triggers} = {}; + + $self->{pbot}->{atexit}->register(sub { $self->save; return; }); + + PBot::RegistryCommands->new(pbot => $self->{pbot}); +} + +sub load { + my $self = shift; + + $self->{pbot}->logger->log("Loading registry from " . $self->{registry}->{filename} . " ...\n"); + + $self->{registry}->load; + + foreach my $section (keys %{ $self->{registry}->hash }) { + foreach my $item (keys %{ $self->{registry}->hash->{$section} }) { + $self->process_trigger($section, $item, $self->{registry}->hash->{$section}->{$item}->{value}); + } + } + + $self->{pbot}->logger->log("Done.\n"); +} + +sub save { + my $self = shift; + $self->{registry}->save; +} + +sub add_default { + my ($self, $type, $section, $item, $value) = @_; + $self->add($type, $section, $item, $value, 1); +} + +sub add { + my $self = shift; + my ($type, $section, $item, $value, $is_default) = @_; + + $type = lc $type; + $section = lc $section; + $item = lc $item; + + $self->{registry}->hash->{$section}->{$item}->{value} = $value; + $self->{registry}->hash->{$section}->{$item}->{type} = $type; + + $self->process_trigger($section, $item, $value) unless $is_default; + $self->save_registry unless $is_default; +} + +sub remove { + my $self = shift; + my ($section, $item) = @_; + + $section = lc $section; + + delete $self->{registry}->hash->{$section}->{$item}; + + if(not scalar keys $self->{registry}->hash->{$section}) { + delete $self->{registry}->hash->{$section}; + } + + $self->save_registry; +} + +sub set { + my ($self, $section, $item, $key, $value) = @_; + + $section = lc $section; + $item = lc $item; + $key = lc $key if defined $key; + + my $oldvalue = $self->get_value($section, $item, 1) if defined $value; + $oldvalue = '' if not defined $oldvalue; + + my $result = $self->{registry}->set($section, $item, $key, $value, 1); + + if(defined $key and $key eq 'value' and defined $value and $oldvalue ne $value) { + $self->process_trigger($section, $item, $value); + } + + return $result; +} + +sub unset { + my ($self, $section, $item, $key) = @_; + + $section = lc $section; + $item = lc $item; + $key = lc $key; + + return $self->{registry}->unset($section, $item, $key); +} + +sub get_value { + my ($self, $section, $item, $as_text) = @_; + + if(exists $self->{registry}->hash->{$section} and exists $self->{registry}->hash->{$section}->{$item}) { + if(not $as_text and $self->{registry}->hash->{$section}->{$item}->{type} eq 'array') { + return split /\s*,\s*/, $self->{registry}->hash->{$section}->{$item}->{value}; + } else { + return $self->{registry}->hash->{$section}->{$item}->{value}; + } + } + return undef; +} + +sub add_trigger { + my ($self, $section, $item, $subref) = @_; + $self->{triggers}->{$section}->{$item} = $subref; +} + +sub process_trigger { + my $self = shift; + my ($section, $item) = @_; + + if(exists $self->{triggers}->{$section} and exists $self->{triggers}->{$section}->{$item}) { + return &{ $self->{triggers}->{$section}->{$item} }(@_); + } + return undef; +} + +1; diff --git a/PBot/RegistryCommands.pm b/PBot/RegistryCommands.pm new file mode 100644 index 00000000..6e85dca9 --- /dev/null +++ b/PBot/RegistryCommands.pm @@ -0,0 +1,240 @@ +# File: RegistryCommands.pm +# Author: pragma_ +# +# Purpose: Commands to introspect and update Registry + +package PBot::RegistryCommands; + +use warnings; +use strict; + +use Carp (); + +sub new { + if(ref($_[1]) eq 'HASH') { + Carp::croak("Options to " . __FILE__ . " should be key/value pairs, not hash reference"); + } + + my ($class, %conf) = @_; + my $self = bless {}, $class; + $self->initialize(%conf); + return $self; +} + +sub initialize { + my ($self, %conf) = @_; + + my $pbot = delete $conf{pbot} // Carp::croak("Missing pbot reference to FactoidCommands"); + $self->{pbot} = $pbot; + + $pbot->commands->register(sub { return $self->regadd(@_) }, "regadd", 60); + $pbot->commands->register(sub { return $self->regrem(@_) }, "regrem", 60); + $pbot->commands->register(sub { return $self->regshow(@_) }, "regshow", 0); + $pbot->commands->register(sub { return $self->regset(@_) }, "regset", 60); + $pbot->commands->register(sub { return $self->regunset(@_) }, "regunset", 60); + $pbot->commands->register(sub { return $self->regchange(@_) }, "regchange", 60); + $pbot->commands->register(sub { return $self->regfind(@_) }, "regfind", 0); +} + +sub regset { + my $self = shift; + my ($from, $nick, $user, $host, $arguments) = @_; + my ($section, $item, $key, $value) = split / /, $arguments, 4 if defined $arguments; + + if(not defined $section or not defined $item) { + return "Usage: regset
[key [value]]"; + } + + $key = undef if not length $key; + $value = undef if not length $value; + + return $self->{pbot}->{registry}->set($section, $item, $key, $value); +} + +sub regunset { + my $self = shift; + my ($from, $nick, $user, $host, $arguments) = @_; + my ($section, $item, $key) = split / /, $arguments, 3 if defined $arguments; + + if(not defined $section or not defined $item or not defined $key) { + return "Usage: regunset
" + } + + return $self->{pbot}->{registry}->unset($section, $item, $key); +} + +sub regadd { + my $self = shift; + my ($from, $nick, $user, $host, $arguments) = @_; + my ($section, $item, $value) = split / /, $arguments, 3 if defined $arguments; + + if(not defined $section or not defined $item or not defined $value) { + return "/msg $nick Usage: regadd
"; + } + + $self->{pbot}->{registry}->add('text', $section, $item, $value); + + $self->{pbot}->logger->log("$nick!$user\@$host added registry entry [$section] $item => $value\n"); + return "/msg $nick [$section] $item set to $value"; +} + +sub regrem { + my $self = shift; + my ($from, $nick, $user, $host, $arguments) = @_; + my ($section, $item) = split / /, $arguments if defined $arguments; + + if(not defined $section or not defined $item) { + return "/msg $nick Usage: regrem
"; + } + + if(not exists $self->{pbot}->{registry}->{registry}->hash->{$section}) { + return "/msg $nick No such registry section $section."; + } + + if(not exists $self->{pbot}->{registry}->{registry}->hash->{$section}->{$item}) { + return "/msg $nick No such item $item in section $section."; + } + + $self->{pbot}->logger->log("$nick!$user\@$host removed registry item [$section][$item]\n"); + $self->{pbot}->{registry}->remove($section, $item); + return "/msg $nick Registry item $item removed from section $section."; +} + +sub regshow { + my $self = shift; + my ($from, $nick, $user, $host, $arguments) = @_; + my $registry = $self->{pbot}->{registry}->{registry}->hash; + + my ($section, $item) = split / /, $arguments if defined $arguments; + + if(not defined $section or not defined $item) { + return "Usage: regshow
"; + } + + if(not exists $registry->{$section}) { + return "/msg $nick No such registry section $section."; + } + + if(not exists $registry->{$section}->{$item}) { + return "/msg $nick No such registry item $item in section $section."; + } + + if($registry->{$section}->{$item}->{private}) { + return "/msg $nick [$section] $item is private."; + } + + my $result = "[$section] $item: $registry->{$section}->{$item}->{value}"; + + if($registry->{$section}->{$item}->{type} eq 'array') { + $result .= ' [array]'; + } + + return $result; +} + +sub regfind { + my $self = shift; + my ($from, $nick, $user, $host, $arguments) = @_; + my $registry = $self->{pbot}->{registry}->{registry}->hash; + + if(not defined $arguments) { + return "/msg $nick Usage: regfind [-section section] "; + } + + my $section; + + $section = $1 if $arguments =~ s/-section\s+([^\b\s]+)//i; + + $arguments =~ s/^\s+//; + $arguments =~ s/\s+$//; + $arguments =~ s/\s+/ /g; + + if($arguments eq "") { + return "/msg $nick Usage: regfind [-section section] "; + } + + my ($text, $last_item, $last_section, $i); + $last_section = ""; + $i = 0; + eval { + foreach my $section_key (sort keys %{ $registry }) { + next if defined $section and $section_key !~ /^$section$/i; + foreach my $item_key (sort keys %{ $registry->{$section_key} }) { + next if $registry->{$section_key}->{$item_key}->{private}; + next if $registry->{$section_key}->{$item_key}->{value} !~ /$arguments/i and $item_key !~ /$arguments/i; + + $i++; + + if($section_key ne $last_section) { + $text .= "[$section_key] "; + $last_section = $section_key; + } + $text .= "$item_key "; + $last_item = $item_key; + } + } + }; + + return "/msg $nick $arguments: $@" if $@; + + if($i == 1) { + chop $text; + return "Found one registry entry: [$last_section] $last_item: $registry->{$last_section}->{$last_item}->{value}"; + } else { + return "found $i registry entries: $text" unless $i == 0; + + my $sections = (defined $section ? "section $section" : 'any sections'); + return "No registry entries matching query found in $sections."; + } +} + +sub regchange { + my $self = shift; + my ($from, $nick, $user, $host, $arguments) = @_; + my ($section, $item, $delim, $tochange, $changeto, $modifier); + + if(defined $arguments) { + if($arguments =~ /^([^\s]+) ([^\s]+)\s+s(.)/) { + $section = $1; + $item = $2; + $delim = $3; + } + + if($arguments =~ /$delim(.*?)$delim(.*)$delim(.*)?$/) { + $tochange = $1; + $changeto = $2; + $modifier = $3; + } + } + + if(not defined $section or not defined $item or not defined $changeto) { + return "Usage: regchange
s///"; + } + + my $registry = $self->{pbot}->{registry}->{registry}->hash; + + if(not exists $registry->{$section}) { + return "/msg $nick No such registry section $section."; + } + + if(not exists $registry->{$section}->{$item}) { + return "/msg $nick No such registry item $item in section $section."; + } + + my $ret = eval { + use re::engine::RE2 -strict => 1; + if(not $registry->{$section}->{$item}->{value} =~ s|$tochange|$changeto|) { + $self->{pbot}->logger->log("($from) $nick!$user\@$host: failed to change [$section] $item 's$delim$tochange$delim$changeto$delim$modifier\n"); + return "/msg $nick Change [$section] $item failed."; + } else { + $self->{pbot}->logger->log("($from) $nick!$user\@$host: changed [$section] $item 's/$tochange/$changeto/\n"); + $self->{pbot}->{registry}->process_trigger($section, $item, 'value', $registry->{$section}->{$item}->{value}); + $self->{pbot}->{registry}->save; + return "Changed: [$section] $item set to $registry->{$section}->{$item}->{value}"; + } + }; + return "/msg $nick Change [$section] $item: $@" if $@; + return $ret; +} + +1; diff --git a/PBot/SelectHandler.pm b/PBot/SelectHandler.pm index a3404238..0b13978a 100644 --- a/PBot/SelectHandler.pm +++ b/PBot/SelectHandler.pm @@ -3,9 +3,6 @@ package PBot::SelectHandler; use warnings; use strict; -use vars qw($VERSION); -$VERSION = '1.0.0'; - use IO::Select; use Carp (); diff --git a/PBot/StdinReader.pm b/PBot/StdinReader.pm index 795cdc22..d80702f4 100644 --- a/PBot/StdinReader.pm +++ b/PBot/StdinReader.pm @@ -3,9 +3,6 @@ package PBot::StdinReader; use warnings; use strict; -use vars qw($VERSION); -$VERSION = '1.0.0'; - use POSIX qw(tcgetpgrp getpgrp); # to check whether process is in background or foreground use Carp (); @@ -46,13 +43,13 @@ sub stdin_reader { if($input =~ m/^~([^ ]+)\s+(.*)/) { $from = $1; - $text = "$self->{pbot}->{trigger}$2"; + $text = $self->{pbot}->{registry}->get_value('general', 'trigger') . $2; } else { - $from = "$self->{pbot}->{botnick}!stdin\@localhost"; - $text = "$self->{pbot}->{trigger}$input"; + $from = $self->{pbot}->{registry}->get_value('irc', 'botnick') . "!stdin\@localhost"; + $text = $self->{pbot}->{registry}->get_value('general', 'trigger') . $input; } - return $self->{pbot}->interpreter->process_line($from, $self->{pbot}->{botnick}, "stdin", "localhost", $text); + return $self->{pbot}->interpreter->process_line($from, $self->{pbot}->{registry}->get_value('irc', 'botnick'), "stdin", "localhost", $text); } 1; diff --git a/PBot/Timer.pm b/PBot/Timer.pm index 874c087b..ced52a66 100644 --- a/PBot/Timer.pm +++ b/PBot/Timer.pm @@ -10,9 +10,6 @@ package PBot::Timer; use warnings; use strict; -use vars qw($VERSION); -$VERSION = '1.0.0'; - use Carp (); our $min_timeout = 10; diff --git a/PBot/VERSION.pm b/PBot/VERSION.pm index e9674d9a..678d36be 100644 --- a/PBot/VERSION.pm +++ b/PBot/VERSION.pm @@ -13,8 +13,8 @@ use warnings; # These are set automatically by the build/commit script use constant { BUILD_NAME => "PBot", - BUILD_REVISION => 581, - BUILD_DATE => "2014-05-16", + BUILD_REVISION => 582, + BUILD_DATE => "2014-05-17", }; 1; diff --git a/pbot.pl b/pbot.pl index 7fec4fc6..14ee88e7 100755 --- a/pbot.pl +++ b/pbot.pl @@ -77,8 +77,8 @@ my %config = ( # You shouldn't need to change anything below this line. # ----------------------------------------------------- - # Maximum messages to remember per nick/hostmask - MAX_NICK_MESSAGES => 256, + # Maximum messages to remember per nick/hostmask in message history + MAX_MESSAGES => 256, # Path to data directory data_dir => "$bothome/data", @@ -94,6 +94,9 @@ my %config = ( log_file => "$bothome/log/log", ); +# Location of file containing configuration registry +$config{registry_file} = "$config{config_dir}/registry"; + # Location of file containing bot admin information $config{admins_file} = "$config{config_dir}/admins";