diff --git a/data/factoids.sqlite3 b/data/factoids.sqlite3 index 87e9e487..0629b9f9 100644 Binary files a/data/factoids.sqlite3 and b/data/factoids.sqlite3 differ diff --git a/lib/PBot/Core.pm b/lib/PBot/Core.pm index 9dd77f83..c97e7ea7 100644 --- a/lib/PBot/Core.pm +++ b/lib/PBot/Core.pm @@ -58,15 +58,18 @@ use PBot::Core::Users; use PBot::Core::Utils::ParseDate; use PBot::Core::WebPaste; +use POSIX qw/EXIT_FAILURE EXIT_SUCCESS/; use Encode; use File::Basename; -# set standard output streams to encode as utf8 -binmode(STDOUT, ":utf8"); -binmode(STDERR, ":utf8"); +BEGIN { + # set standard output streams to encode as utf8 + binmode(STDOUT, ":utf8"); + binmode(STDERR, ":utf8"); -# decode command-line arguments from utf8 -@ARGV = map { decode('UTF-8', $_, 1) } @ARGV; + # decode command-line arguments from utf8 + @ARGV = map { decode('UTF-8', $_, 1) } @ARGV; +} sub new { my ($class, %args) = @_; @@ -96,14 +99,14 @@ sub initialize { if (not defined $item or not defined $value) { print STDERR "Fatal error: unknown argument `$arg`; arguments must be in the form of `section.key=value` or `path_dir=value` (e.g.: irc.botnick=newnick or data_dir=path)\n"; - exit; + exit EXIT_FAILURE; } my ($section, $key) = split /\./, $item, 2; if (not defined $section or not defined $key) { print STDERR "Fatal error: bad argument `$arg`; registry entries must be in the form of section.key (e.g.: irc.botnick)\n"; - exit; + exit EXIT_FAILURE; } $section =~ s/^-//; # remove a leading - to allow arguments like -irc.botnick due to habitual use of -args @@ -115,14 +118,14 @@ sub initialize { foreach my $path (qw/data_dir applet_dir update_dir/) { if (not -d $conf{$path}) { print STDERR "$path path ($conf{$path}) does not exist; aborting.\n"; - exit; + exit EXIT_FAILURE; } } # insist that data directory be copied if (basename($conf{data_dir}) eq 'data') { print STDERR "Data directory ($conf{data_dir}) cannot be named `data`. This is to ensure the directory is copied from its default location. Please follow doc/QuickStart.md.\n"; - exit; + exit EXIT_FAILURE; } # let modules register atexit subroutines @@ -151,9 +154,9 @@ sub initialize { # update any data files to new locations/formats # --- this must happen before any data files are opened! --- - if ($self->{updater}->update) { + if ($self->{updater}->update != EXIT_SUCCESS) { $self->{logger}->log("Update failed.\n"); - exit 0; + exit EXIT_FAILURE; } # create capabilities so commands can add new capabilities @@ -167,8 +170,8 @@ sub initialize { # ensure user has attempted to configure the bot if (not length $self->{registry}->get_value('irc', 'botnick')) { - $self->{logger}->log("Fatal error: IRC nickname not defined; please set registry key irc.botnick in $conf{data_dir}/registry to continue.\n"); - exit; + $self->{logger}->log("Fatal error: IRC nickname not defined; please set registry key irc.botnick in $conf{data_dir}/registry to continue. See doc/QuickStart.md for more information.\n"); + exit EXIT_FAILURE; } # prepare the IRC engine @@ -234,11 +237,8 @@ sub random_nick { # TODO: add disconnect subroutine and connect/disconnect/reconnect commands sub connect { my ($self) = @_; - return if $ENV{PBOT_LOCAL}; - if ($self->{connected}) { - # TODO: disconnect, clean-up, etc - } + return if $ENV{PBOT_LOCAL}; my $server = $self->{registry}->get_value('irc', 'server'); my $port = $self->{registry}->get_value('irc', 'port'); @@ -247,6 +247,11 @@ sub connect { $self->{logger}->log("Connecting to $server:$port\n"); + if ($self->{conn}) { + $self->{logger}->log("Error: already connected to $server:$port!\n"); + return; + } + for (my $attempt = 0; $attempt < $retries; $attempt++) { my %config = ( Nick => $self->{registry}->get_value('irc', 'randomize_nick') ? $self->random_nick : $self->{registry}->get_value('irc', 'botnick'), @@ -285,7 +290,10 @@ sub connect { sleep $delay; } - $self->{connected} = 1; + if (!$self->{conn}) { + $self->{logger}->log("Max retries reached; giving up.\n"); + $self->exit(EXIT_FAILURE); + } # set up IRC handlers $self->{irchandlers}->add_handlers; @@ -302,7 +310,7 @@ sub register_signal_handlers { print $msg; } $self->atexit; - exit 0; + exit EXIT_SUCCESS; }; } @@ -320,7 +328,7 @@ sub atexit { # convenient function to exit PBot sub exit { my ($self, $exitval) = @_; - $exitval //= 0; + $exitval //= EXIT_SUCCESS; my $msg = "Exiting immediately.\n"; diff --git a/lib/PBot/Core/Handlers/SASL.pm b/lib/PBot/Core/Handlers/SASL.pm index 1cca8b8d..c22575b7 100644 --- a/lib/PBot/Core/Handlers/SASL.pm +++ b/lib/PBot/Core/Handlers/SASL.pm @@ -10,6 +10,7 @@ package PBot::Core::Handlers::SASL; use PBot::Imports; use parent 'PBot::Core::Class'; +use POSIX qw/EXIT_SUCCESS EXIT_FAILURE/; use Encode; use MIME::Base64; @@ -36,7 +37,7 @@ sub on_sasl_authenticate { if (not defined $password or not length $password) { $self->{pbot}->{logger}->log("Error: Registry entry irc.identify_password is not set.\n"); - $self->{pbot}->exit; + $self->{pbot}->exit(EXIT_FAILURE); } $password = encode('UTF-8', "$nick\0$nick\0$password"); @@ -72,7 +73,7 @@ sub on_rpl_loggedout { sub on_err_nicklocked { my ($self, $event_type, $event) = @_; $self->{pbot}->{logger}->log($event->{event}->{args}->[1] . "\n"); - $self->{pbot}->exit; + $self->{pbot}->exit(EXIT_FAILURE); } sub on_rpl_saslsuccess { @@ -85,19 +86,19 @@ sub on_rpl_saslsuccess { sub on_err_saslfail { my ($self, $event_type, $event) = @_; $self->{pbot}->{logger}->log($event->{event}->{args}->[1] . "\n"); - $self->{pbot}->exit; + $self->{pbot}->exit(EXIT_FAILURE); } sub on_err_sasltoolong { my ($self, $event_type, $event) = @_; $self->{pbot}->{logger}->log($event->{event}->{args}->[1] . "\n"); - $self->{pbot}->exit; + $self->{pbot}->exit(EXIT_FAILURE); } sub on_err_saslaborted { my ($self, $event_type, $event) = @_; $self->{pbot}->{logger}->log($event->{event}->{args}->[1] . "\n"); - $self->{pbot}->exit; + $self->{pbot}->exit(EXIT_FAILURE); } sub on_err_saslalready { @@ -110,7 +111,7 @@ sub on_rpl_saslmechs { my ($self, $event_type, $event) = @_; $self->{pbot}->{logger}->log("SASL mechanism not available.\n"); $self->{pbot}->{logger}->log("Available mechanisms are: $event->{event}->{args}->[1]\n"); - $self->{pbot}->exit; + $self->{pbot}->exit(EXIT_FAILURE); } 1; diff --git a/lib/PBot/Core/Handlers/Server.pm b/lib/PBot/Core/Handlers/Server.pm index 7353fb87..f8219f34 100644 --- a/lib/PBot/Core/Handlers/Server.pm +++ b/lib/PBot/Core/Handlers/Server.pm @@ -58,7 +58,7 @@ sub on_disconnect { my ($self, $event_type, $event) = @_; $self->{pbot}->{logger}->log("Disconnected...\n"); - $self->{pbot}->{connected} = 0; + $self->{pbot}->{conn} = undef; # send pbot.disconnect to notify PBot internals $self->{pbot}->{event_dispatcher}->dispatch_event( diff --git a/lib/PBot/Core/Interpreter.pm b/lib/PBot/Core/Interpreter.pm index 1a4891b8..f4bdf679 100644 --- a/lib/PBot/Core/Interpreter.pm +++ b/lib/PBot/Core/Interpreter.pm @@ -209,7 +209,7 @@ sub process_line { # set $context's command output recipient field if ($nick_prefix) { - $context->{nickprefix} = $nick_prefix; + $context->{nickprefix} = $nick_prefix; $context->{nickprefix_forced} = 1; } diff --git a/lib/PBot/Core/Registry.pm b/lib/PBot/Core/Registry.pm index 48ca924e..94a4585f 100644 --- a/lib/PBot/Core/Registry.pm +++ b/lib/PBot/Core/Registry.pm @@ -99,7 +99,7 @@ sub trigger_irc_debug { $self->{pbot}->{irc}->debug($newvalue); - if ($self->{pbot}->{connected}) { + if ($self->{pbot}->{conn}) { $self->{pbot}->{conn}->debug($newvalue); } } @@ -107,7 +107,7 @@ sub trigger_irc_debug { sub trigger_change_botnick { my ($self, $section, $item, $newvalue) = @_; - if ($self->{pbot}->{connected}) { + if ($self->{pbot}->{conn}) { $self->{pbot}->{conn}->nick($newvalue) } } diff --git a/lib/PBot/VERSION.pm b/lib/PBot/VERSION.pm index f27bf0ae..4683c195 100644 --- a/lib/PBot/VERSION.pm +++ b/lib/PBot/VERSION.pm @@ -25,8 +25,8 @@ use PBot::Imports; # These are set by the /misc/update_version script use constant { BUILD_NAME => "PBot", - BUILD_REVISION => 4557, - BUILD_DATE => "2022-07-09", + BUILD_REVISION => 4558, + BUILD_DATE => "2022-07-10", }; sub initialize {}