3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-19 18:39:35 +01:00
pbot/PBot/BotAdmins.pm
Pragmatic Software d955bfa06c Add centralized configuration registry module
Allows changing of bot configuration values without needing to restart
bot instance or needing to edit pbot.pl script.

Registry will initially be populated with default values from pbot.pl,
but if a registry file exists then the registry values will take
precedence over the pbot.pl values. For instance, if you regset the
bot trigger to '%' then the trigger will be '%' even if pbot.pl has '!'
or something else explicitly set.

Some registry items can have trigger hooks associated with them.  For
instance, the irc->botnick registry entry has a change_botnick_trigger
associated with it which changes the IRC nick on the server when a new
value is set via regset/regadd.

Tons of other fixes and improvements throughout.
2014-05-17 20:08:19 +00:00

253 lines
6.1 KiB
Perl

# File: BotAdmins.pm
# Author: pragma_
#
# Purpose: Manages list of bot admins and whether they are logged in.
package PBot::BotAdmins;
use warnings;
use strict;
use PBot::DualIndexHashObject;
use Carp ();
sub new {
if(ref($_[1]) eq 'HASH') {
Carp::croak("Options to BotAdmins 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 $filename = delete $conf{filename};
my $export_path = delete $conf{export_path};
my $export_site = delete $conf{export_site};
my $pbot = delete $conf{pbot};
if(not defined $pbot) {
Carp::croak("Missing pbot reference to BotAdmins");
}
my $export_timeout = delete $conf{export_timeout};
if(not defined $export_timeout) {
if(defined $export_path) {
$export_timeout = 300; # every 5 minutes
} else {
$export_timeout = -1;
}
}
$self->{admins} = PBot::DualIndexHashObject->new(name => 'Admins', filename => $filename);
$self->{export_path} = $export_path;
$self->{export_site} = $export_site;
$self->{export_timeout} = $export_timeout;
$self->{pbot} = $pbot;
}
sub add_admin {
my $self = shift;
my ($name, $channel, $hostmask, $level, $password, $dont_save) = @_;
$channel = lc $channel;
$hostmask = lc $hostmask;
$self->admins->hash->{$channel}->{$hostmask}->{name} = $name;
$self->admins->hash->{$channel}->{$hostmask}->{level} = $level;
$self->admins->hash->{$channel}->{$hostmask}->{password} = $password;
$self->{pbot}->logger->log("Adding new level $level admin: [$name] [$hostmask] for channel [$channel]\n");
$self->save_admins unless $dont_save;
}
sub remove_admin {
my $self = shift;
my ($channel, $hostmask) = @_;
my $admin = delete $self->admins->hash->{$channel}->{$hostmask};
if(defined $admin) {
$self->{pbot}->logger->log("Removed level $admin->{level} admin [$admin->{name}] [$hostmask] from channel [$channel]\n");
$self->save_admins;
return 1;
} else {
$self->{pbot}->logger->log("Attempt to remove non-existent admin [$hostmask] from channel [$channel]\n");
return 0;
}
}
sub load_admins {
my $self = shift;
my $filename;
if(@_) { $filename = shift; } else { $filename = $self->admins->filename; }
if(not defined $filename) {
Carp::carp "No admins path specified -- skipping loading of admins";
return;
}
$self->{pbot}->logger->log("Loading admins from $filename ...\n");
$self->admins->load;
my $i = 0;
foreach my $channel (keys %{ $self->admins->hash } ) {
foreach my $hostmask (keys %{ $self->admins->hash->{$channel} }) {
$i++;
my $name = $self->admins->hash->{$channel}->{$hostmask}->{name};
my $level = $self->admins->hash->{$channel}->{$hostmask}->{level};
my $password = $self->admins->hash->{$channel}->{$hostmask}->{password};
if(not defined $name or not defined $level or not defined $password) {
Carp::croak "Syntax error around line $i of $filename\n";
}
$self->{pbot}->logger->log("Adding new level $level admin: [$name] [$hostmask] for channel [$channel]\n");
}
}
$self->{pbot}->logger->log(" $i admins loaded.\n");
$self->{pbot}->logger->log("Done.\n");
}
sub save_admins {
my $self = shift;
$self->admins->save;
$self->export_admins;
}
sub export_admins {
my $self = shift;
my $filename;
if(@_) { $filename = shift; } else { $filename = $self->export_path; }
return if not defined $filename;
return;
}
sub find_admin {
my ($self, $from, $hostmask) = @_;
$from = $self->{pbot}->{registry}->get_value('irc', 'botnick') if not defined $from;
$hostmask = '.*' if not defined $hostmask;
my $result = eval {
foreach my $channel_regex (keys %{ $self->admins->hash }) {
if($from !~ m/^#/) {
# if not from a channel, make sure that nick portion of hostmask matches $from
foreach my $hostmask_regex (keys %{ $self->admins->hash->{$channel_regex} }) {
my $nick;
if($hostmask_regex =~ m/^([^!]+)!.*/) {
$nick = $1;
} else {
$nick = $hostmask_regex;
}
return $self->admins->hash->{$channel_regex}->{$hostmask_regex} if($from =~ m/$nick/i and $hostmask =~ m/$hostmask_regex/i);
}
} elsif($from =~ m/$channel_regex/i) {
foreach my $hostmask_regex (keys %{ $self->admins->hash->{$channel_regex} }) {
return $self->admins->hash->{$channel_regex}->{$hostmask_regex} if $hostmask =~ m/$hostmask_regex/i;
}
}
}
return undef;
};
if($@) {
$self->{pbot}->logger->log("Error in find_admin parameters: $@\n");
}
return $result;
}
sub loggedin {
my ($self, $channel, $hostmask) = @_;
my $admin = $self->find_admin($channel, $hostmask);
if(defined $admin && exists $admin->{loggedin}) {
return $admin;
} else {
return undef;
}
}
sub login {
my ($self, $channel, $hostmask, $password) = @_;
my $admin = $self->find_admin($channel, $hostmask);
if(not defined $admin) {
$self->{pbot}->logger->log("Attempt to login non-existent [$channel][$hostmask] failed\n");
return "You do not have an account in $channel.";
}
if($admin->{password} ne $password) {
$self->{pbot}->logger->log("Bad login password for [$channel][$hostmask]\n");
return "I don't think so.";
}
$admin->{loggedin} = 1;
$self->{pbot}->logger->log("$hostmask logged into $channel\n");
return "Logged into $channel.";
}
sub logout {
my ($self, $channel, $hostmask) = @_;
my $admin = $self->find_admin($channel, $hostmask);
delete $admin->{loggedin} if defined $admin;
}
sub export_path {
my $self = shift;
if(@_) { $self->{export_path} = shift; }
return $self->{export_path};
}
sub export_timeout {
my $self = shift;
if(@_) { $self->{export_timeout} = shift; }
return $self->{export_timeout};
}
sub export_site {
my $self = shift;
if(@_) { $self->{export_site} = shift; }
return $self->{export_site};
}
sub admins {
my $self = shift;
return $self->{admins};
}
sub filename {
my $self = shift;
if(@_) { $self->{filename} = shift; }
return $self->{filename};
}
1;