3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-23 12:29:27 +01:00

Commands now stored as hash table

This commit is contained in:
Pragmatic Software 2021-07-23 18:26:07 -07:00
parent 2bda82dd4b
commit 6fd4245b2e
2 changed files with 91 additions and 91 deletions

View File

@ -7,7 +7,7 @@
# SPDX-License-Identifier: MIT # SPDX-License-Identifier: MIT
package PBot::Core::Commands; package PBot::Core::Commands;
use parent 'PBot::Core::Class', 'PBot::Core::Registerable'; use parent 'PBot::Core::Class';
use PBot::Imports; use PBot::Imports;
@ -16,19 +16,24 @@ use PBot::Utils::LoadModules qw/load_modules/;
sub initialize { sub initialize {
my ($self, %conf) = @_; my ($self, %conf) = @_;
# PBot::Core::Commands can register subrefs # registered commands hash table
$self->PBot::Core::Registerable::initialize(%conf); $self->{commands} = {};
# command metadata stored as a HashObject # command metadata stored as a HashObject
$self->{metadata} = PBot::Storage::HashObject->new(pbot => $self->{pbot}, name => 'Command metadata', filename => $conf{filename}); $self->{metadata} = PBot::Storage::HashObject->new(
pbot => $self->{pbot},
name => 'Command metadata',
filename => $conf{filename},
);
$self->{metadata}->load; $self->{metadata}->load;
} }
sub register_commands { sub load_commands {
my ($self) = @_; my ($self) = @_;
# register commands in Commands directory # load commands in Commands directory
$self->{pbot}->{logger}->log("Registering commands:\n"); $self->{pbot}->{logger}->log("Loading commands:\n");
load_modules($self, 'PBot::Core::Commands'); load_modules($self, 'PBot::Core::Commands');
} }
@ -39,15 +44,21 @@ sub register {
Carp::croak("Missing parameters to Commands::register"); Carp::croak("Missing parameters to Commands::register");
} }
# register subref $name = lc $name;
my $command = $self->PBot::Core::Registerable::register($subref);
# update internal metadata if (exists $self->{commands}->{$name}) {
$command->{name} = lc $name; $self->{pbot}->{logger}->log("Commands: warning: overwriting existing command $name\n");
$command->{requires_cap} = $requires_cap // 0; }
# register command
$self->{commands}->{$name} = {
requires_cap => $requires_cap // 0,
subref => $subref,
};
# update command metadata # update command metadata
if (not $self->{metadata}->exists($name)) { if (not $self->{metadata}->exists($name)) {
# create new metadata
$self->{metadata}->add($name, { requires_cap => $requires_cap, help => '' }, 1); $self->{metadata}->add($name, { requires_cap => $requires_cap, help => '' }, 1);
} else { } else {
# metadata already exists, just update requires_cap unless it's already set. # metadata already exists, just update requires_cap unless it's already set.
@ -60,22 +71,18 @@ sub register {
if ($requires_cap) { if ($requires_cap) {
$self->{pbot}->{capabilities}->add("can-$name", undef, 1); $self->{pbot}->{capabilities}->add("can-$name", undef, 1);
} }
return $command;
} }
sub unregister { sub unregister {
my ($self, $name) = @_; my ($self, $name) = @_;
Carp::croak("Missing name parameter to Commands::unregister") if not defined $name; Carp::croak("Missing name parameter to Commands::unregister") if not defined $name;
$name = lc $name; $name = lc $name;
@{$self->{handlers}} = grep { $_->{name} ne $name } @{$self->{handlers}}; delete $self->{commands}->{$name};
} }
sub exists { sub exists {
my ($self, $keyword) = @_; my ($self, $name) = @_;
$keyword = lc $keyword; return exists $self->{commands}->{lc $name};
foreach my $command (@{$self->{handlers}}) { return 1 if $command->{name} eq $keyword; }
return 0;
} }
sub set_meta { sub set_meta {
@ -107,6 +114,12 @@ sub interpreter {
my $keyword = lc $context->{keyword}; my $keyword = lc $context->{keyword};
my $from = $context->{from}; my $from = $context->{from};
# alias to the command
my $command = $self->{commands}->{$keyword};
# bail early if the command doesn't exist
return undef if not defined $command;
# set the channel the command is in reference to # set the channel the command is in reference to
my ($cmd_channel) = $context->{arguments} =~ m/\B(#[^ ]+)/; # assume command is invoked in regards to first channel-like argument my ($cmd_channel) = $context->{arguments} =~ m/\B(#[^ ]+)/; # assume command is invoked in regards to first channel-like argument
$cmd_channel = $from if not defined $cmd_channel; # otherwise command is invoked in regards to the channel the user is in $cmd_channel = $from if not defined $cmd_channel; # otherwise command is invoked in regards to the channel the user is in
@ -124,16 +137,10 @@ sub interpreter {
$cap_override = $context->{'cap-override'}; $cap_override = $context->{'cap-override'};
} }
# go through all commands
# TODO: maybe use a hash lookup
foreach my $command (@{$self->{handlers}}) {
# is this the command
if ($command->{name} eq $keyword) {
# does this command require capabilities # does this command require capabilities
my $requires_cap = $self->get_meta($keyword, 'requires_cap') // $command->{requires_cap}; my $requires_cap = $self->get_meta($keyword, 'requires_cap') // $command->{requires_cap};
# validate can-command capability
if ($requires_cap) { if ($requires_cap) {
if (defined $cap_override) { if (defined $cap_override) {
if (not $self->{pbot}->{capabilities}->has($cap_override, "can-$keyword")) { if (not $self->{pbot}->{capabilities}->has($cap_override, "can-$keyword")) {
@ -167,12 +174,8 @@ sub interpreter {
$context->{arglist} = $self->{pbot}->{interpreter}->make_args($context->{arguments}); $context->{arglist} = $self->{pbot}->{interpreter}->make_args($context->{arguments});
} }
# $self->{pbot}->{logger}->log("Disabling nickprefix\n"); # execute this command as a backgrounded process?
#$context->{nickprefix_disabled} = 1;
if ($self->get_meta($keyword, 'background-process')) { if ($self->get_meta($keyword, 'background-process')) {
# execute this command as a backgrounded process
# set timeout to command metadata value # set timeout to command metadata value
my $timeout = $self->get_meta($keyword, 'process-timeout'); my $timeout = $self->get_meta($keyword, 'process-timeout');
@ -193,15 +196,11 @@ sub interpreter {
my $result = $command->{subref}->($context); my $result = $command->{subref}->($context);
# disregard undesired command output if command is embedded # disregard undesired command output if command is embedded
return undef if $context->{referenced} and $result =~ m/(?:usage:|no results)/i; return undef if $context->{embedded} and $result =~ m/(?:usage:|no results)/i;
# return command output # return command output
return $result; return $result;
} }
} }
}
return undef;
}
1; 1;

View File

@ -94,12 +94,13 @@ sub cmd_list {
} }
if ($context->{arguments} =~ /^commands$/i) { if ($context->{arguments} =~ /^commands$/i) {
my $commands = $self->{pbot}->{commands}->{commands};
$text = 'Registered commands: '; $text = 'Registered commands: ';
foreach my $command (sort { $a->{name} cmp $b->{name} } @{$self->{pbot}->{commands}->{handlers}}) { foreach my $command (sort keys %$commands) {
if ($command->{requires_cap}) { if ($commands->{$command}->{requires_cap}) {
$text .= "+$command->{name} "; $text .= "+$command ";
} else { } else {
$text .= "$command->{name} "; $text .= "$command ";
} }
} }