From f3ef8a56c02dc0c77f524d725dc033961df3d6e2 Mon Sep 17 00:00:00 2001 From: Pragmatic Software Date: Sat, 18 Jan 2020 21:49:55 -0800 Subject: [PATCH] Commands: add metadata --- PBot/Commands.pm | 82 ++++++++++++++++++++++++++++++------------------ PBot/PBot.pm | 10 +++--- 2 files changed, 56 insertions(+), 36 deletions(-) diff --git a/PBot/Commands.pm b/PBot/Commands.pm index 230a1e98..3c245a09 100644 --- a/PBot/Commands.pm +++ b/PBot/Commands.pm @@ -20,14 +20,11 @@ use feature 'unicode_strings'; use base 'PBot::Registerable'; use Carp (); +use PBot::HashObject; sub new { - if (ref($_[1]) eq 'HASH') { - Carp::croak("Options to Commands should be key/value pairs, not hash reference"); - } - + 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; @@ -35,52 +32,43 @@ sub new { sub initialize { my ($self, %conf) = @_; - $self->SUPER::initialize(%conf); + $self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__); - my $pbot = delete $conf{pbot}; - if (not defined $pbot) { - Carp::croak("Missing pbot reference to PBot::Commands"); - } + $self->{metadata} = PBot::HashObject->new(pbot => $self->{pbot}, name => 'Commands metadata', filename => $conf{filename}); + $self->load_metadata; - $self->{pbot} = $pbot; - $self->{name} = undef; - $self->{level} = undef; + $self->register(sub { $self->set(@_); }, "cmdset", 90); + $self->register(sub { $self->unset(@_); }, "cmdunset", 90); } sub register { my ($self, $subref, $name, $level) = @_; - if ((not defined $subref) || (not defined $name) || (not defined $level)) { + if (not defined $subref or not defined $name or not defined $level) { Carp::croak("Missing parameters to Commands::register"); } - $name = lc $name; - my $ref = $self->SUPER::register($subref); - - $ref->{name} = $name; + $ref->{name} = lc $name; $ref->{level} = $level; + if (not $self->{metadata}->exists($name)) { + $self->{metadata}->add($name, { level => $level, help => '' }, 1); + } + return $ref; } sub unregister { my ($self, $name) = @_; - - if (not defined $name) { - Carp::croak("Missing name parameter to Commands::unregister"); - } - + Carp::croak("Missing name parameter to Commands::unregister") if not defined $name; $name = lc $name; - @{ $self->{handlers} } = grep { $_->{name} ne $name } @{ $self->{handlers} }; } sub exists { - my $self = shift; - my ($keyword) = @_; - + my ($self, $keyword) = @_; $keyword = lc $keyword; foreach my $ref (@{ $self->{handlers} }) { return 1 if $ref->{name} eq $keyword; @@ -103,17 +91,18 @@ sub interpreter { my ($admin_channel) = $stuff->{arguments} =~ m/\B(#[^ ]+)/; # assume first channel-like argument $admin_channel = $from if not defined $admin_channel; my $admin = $self->{pbot}->{admins}->loggedin($admin_channel, "$stuff->{nick}!$stuff->{user}\@$stuff->{host}"); - my $level = defined $admin ? $admin->{level} : 0; + my $admin_level = defined $admin ? $admin->{level} : 0; my $keyword = lc $stuff->{keyword}; if (exists $stuff->{'effective-level'}) { $self->{pbot}->{logger}->log("override level to $stuff->{'effective-level'}\n"); - $level = $stuff->{'effective-level'}; + $admin_level = $stuff->{'effective-level'}; } foreach my $ref (@{ $self->{handlers} }) { if ($ref->{name} eq $keyword) { - if ($level >= $ref->{level}) { + my $cmd_level = $self->get_meta($keyword, 'level') // $ref->{level}; + if ($admin_level >= $cmd_level) { $stuff->{no_nickoverride} = 1; my $result = &{ $ref->{subref} }($stuff->{from}, $stuff->{nick}, $stuff->{user}, $stuff->{host}, $stuff->{arguments}, $stuff); if ($stuff->{referenced}) { @@ -122,7 +111,7 @@ sub interpreter { return $result; } else { return undef if $stuff->{referenced}; - if ($level == 0) { + if ($admin_level == 0) { return "/msg $stuff->{nick} You must login to use this command."; } else { return "/msg $stuff->{nick} You are not authorized to use this command."; @@ -134,4 +123,35 @@ sub interpreter { return undef; } +sub set { + my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_; + my ($command, $key, $value) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3); + return "Usage: cmdset [key [value]]" if not defined $command; + return $self->{metadata}->set($command, $key, $value); +} + +sub unset { + my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_; + my ($command, $key) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2); + return "Usage: cmdunset " if not defined $command or not defined $key; + return $self->{metadata}->unset($command, $key); +} + +sub get_meta { + my ($self, $command, $key) = @_; + $command = lc $command; + return undef if not exists $self->{metadata}->{hash}->{$command}; + return $self->{metadata}->{hash}->{$command}->{$key}; +} + +sub load_metadata { + my ($self) = @_; + $self->{metadata}->load; +} + +sub save_metadata { + my ($self) = @_; + $self->{metadata}->save; +} + 1; diff --git a/PBot/PBot.pm b/PBot/PBot.pm index 124d3d8e..ef4b7a40 100644 --- a/PBot/PBot.pm +++ b/PBot/PBot.pm @@ -89,11 +89,6 @@ sub initialize { return if $conf{logger_only}; - $self->{timer} = PBot::Timer->new(timeout => 10, %conf); - $self->{commands} = PBot::Commands->new(pbot => $self, %conf); - $self->{func_cmd} = PBot::FuncCommand->new(pbot => $self, %conf); - $self->{refresher} = PBot::Refresher->new(pbot => $self); - # make sure the environment is sane if (not -d $data_dir) { $self->{logger}->log("Data directory ($data_dir) does not exist; aborting...\n"); @@ -114,6 +109,11 @@ sub initialize { $self->{logger}->log("module_dir: $module_dir\n"); $self->{logger}->log("plugin_dir: $plugin_dir\n"); + $self->{timer} = PBot::Timer->new(timeout => 10, %conf); + $self->{commands} = PBot::Commands->new(pbot => $self, filename => "$data_dir/commands", %conf); + $self->{func_cmd} = PBot::FuncCommand->new(pbot => $self, %conf); + $self->{refresher} = PBot::Refresher->new(pbot => $self); + # create registry and set some defaults $self->{registry} = PBot::Registry->new(pbot => $self, filename => "$data_dir/registry", %conf);