pbot/lib/PBot/Core/Handlers/NickServ.pm

125 lines
4.8 KiB
Perl

# File: NickServ.pm
#
# Purpose: Handles NickServ-related IRC events.
# SPDX-FileCopyrightText: 2005-2023 Pragmatic Software <pragma78@gmail.com>
# SPDX-License-Identifier: MIT
package PBot::Core::Handlers::NickServ;
use PBot::Imports;
use parent 'PBot::Core::Class';
sub initialize {
my ($self, %conf) = @_;
# NickServ-related IRC events get priority 10
# priority is from 0 to 100 where 0 is highest and 100 is lowest
$self->{pbot}->{event_dispatcher}->register_handler('irc.welcome', sub { $self->on_welcome (@_) }, 10);
$self->{pbot}->{event_dispatcher}->register_handler('irc.notice', sub { $self->on_notice (@_) }, 10);
$self->{pbot}->{event_dispatcher}->register_handler('irc.nicknameinuse', sub { $self->on_nicknameinuse (@_) }, 10);
}
sub on_welcome {
my ($self, $event_type, $event) = @_;
# if not using SASL, identify the old way by msging NickServ or some services bot
if (not $self->{pbot}->{irc_capabilities}->{sasl}) {
if (length $self->{pbot}->{registry}->get_value('irc', 'identify_password')) {
my $nickserv = $self->{pbot}->{registry}->get_value('general', 'identify_nick') // 'NickServ';
my $command = $self->{pbot}->{registry}->get_value('general', 'identify_command') // 'identify $nick $password';
$self->{pbot}->{logger}->log("Identifying with $nickserv . . .\n");
my $botnick = $self->{pbot}->{registry}->get_value('irc', 'botnick');
my $password = $self->{pbot}->{registry}->get_value('irc', 'identify_password');
$command =~ s/\$nick\b/$botnick/g;
$command =~ s/\$password\b/$password/g;
$event->{conn}->privmsg($nickserv, $command);
} else {
$self->{pbot}->{logger}->log("No identify password; skipping identification to services.\n");
}
# auto-join channels unless general.autojoin_wait_for_nickserv is true
if (not $self->{pbot}->{registry}->get_value('general', 'autojoin_wait_for_nickserv')) {
$self->{pbot}->{logger}->log("Autojoining channels immediately; to wait for services set general.autojoin_wait_for_nickserv to 1.\n");
$self->{pbot}->{channels}->autojoin;
} else {
$self->{pbot}->{logger}->log("Waiting for services identify response before autojoining channels.\n");
}
return 1;
}
# event not handled
return undef;
}
sub on_notice {
my ($self, $event_type, $event) = @_;
my ($nick, $user, $host, $to, $text) = (
$event->nick,
$event->user,
$event->host,
$event->to,
$event->{args}[0],
);
my $nickserv = $self->{pbot}->{registry}->get_value('general', 'identify_nick') // 'NickServ';
# notice from NickServ
if (lc $nick eq lc $nickserv) {
# log notice
$self->{pbot}->{logger}->log("NOTICE from $nick!$user\@$host to $to: $text\n");
# if we have enabled NickServ GUARD protection and we're not identified yet,
# NickServ will warn us to identify -- this is our cue to identify.
if ($text =~ m/This nickname is registered/) {
if (length $self->{pbot}->{registry}->get_value('irc', 'identify_password')) {
$self->{pbot}->{logger}->log("Identifying with NickServ . . .\n");
$event->{conn}->privmsg("nickserv", "identify " . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
}
}
elsif ($text =~ m/You are now identified/) {
# we have identified with NickServ
if ($self->{pbot}->{registry}->get_value('irc', 'randomize_nick')) {
# if irc.randomize_nicks was enabled, we go ahead and attempt to
# change to our real botnick. we don't auto-join channels just yet in case
# the nick change fails.
$event->{conn}->nick($self->{pbot}->{registry}->get_value('irc', 'botnick'));
} else {
# otherwise go ahead and autojoin channels now
$self->{pbot}->{channels}->autojoin;
}
}
elsif ($text =~ m/has been ghosted/) {
# we have ghosted someone using our botnick, let's attempt to regain it now
$event->{conn}->nick($self->{pbot}->{registry}->get_value('irc', 'botnick'));
}
return 1;
}
# event not handled
return undef;
}
sub on_nicknameinuse {
my ($self, $event_type, $event) = @_;
my (undef, $nick, $msg) = $event->args;
my $from = $event->from;
$self->{pbot}->{logger}->log("Received nicknameinuse for nick $nick from $from: $msg\n");
# attempt to use NickServ GHOST command to kick nick off
$event->{conn}->privmsg("nickserv", "ghost $nick " . $self->{pbot}->{registry}->get_value('irc', 'identify_password'));
return 1;
}
1;