3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-12-24 03:33:06 +01:00

Update all commands to understand quoted arguments; factoid names, etc, can now contain spaces

This commit is contained in:
Pragmatic Software 2018-08-08 17:38:57 -07:00
parent bbe817cd28
commit 174de2be8e
11 changed files with 186 additions and 130 deletions

View File

@ -126,10 +126,12 @@ sub whitelisted {
}
sub whitelist {
my ($self, $from, $nick, $user, $host, $arguments) = @_;
$arguments = lc $arguments;
my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($command, $args) = split /\s+/, $arguments, 2;
my $arglist = $stuff->{arglist};
$self->{pbot}->{interpreter}->lc_args($arglist);
my $command = $self->{pbot}->{interpreter}->shift_arg($arglist);
return "Usage: whitelist <command>, where commands are: list/show, add, remove, set, unset" if not defined $command;
@ -153,7 +155,7 @@ sub whitelist {
return $text;
}
when ("set") {
my ($channel, $mask, $flag, $value) = split /\s+/, $args, 4;
my ($channel, $mask, $flag, $value) = $self->{pbot}->{interpreter}->split_args($arglist, 4);
return "Usage: whitelist set <channel> <mask> [flag] [value]" if not defined $channel or not defined $mask;
if (not exists $self->{whitelist}->hash->{$channel}) {
@ -194,7 +196,7 @@ sub whitelist {
return "Flag set.";
}
when ("unset") {
my ($channel, $mask, $flag) = split /\s+/, $args, 3;
my ($channel, $mask, $flag) = $self->{pbot}->{interpreter}->split_args($arglist, 3);
return "Usage: whitelist unset <channel> <mask> <flag>" if not defined $channel or not defined $mask or not defined $flag;
if (not exists $self->{whitelist}->hash->{$channel}) {
@ -214,7 +216,7 @@ sub whitelist {
return "Flag unset.";
}
when ("add") {
my ($channel, $mask, $mode) = split /\s+/, $args, 3;
my ($channel, $mask, $mode) = $self->{pbot}->{interpreter}->split_args($arglist, 3);
return "Usage: whitelist add <channel> <mask> [mode (user or ban, default: user)]" if not defined $channel or not defined $mask;
$mode = 'user' if not defined $mode;
@ -231,7 +233,7 @@ sub whitelist {
return "/say $mask whitelisted in channel $channel";
}
when ("remove") {
my ($channel, $mask) = split /\s+/, $args, 2;
my ($channel, $mask) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
return "Usage: whitelist remove <channel> <mask>" if not defined $channel or not defined $mask;
if(not defined $self->{whitelist}->hash->{$channel}) {

View File

@ -70,9 +70,9 @@ sub is_spam {
sub antispam_cmd {
my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_;
my @pargs = @{$stuff->{argumentspos}};
my $arglist = $stuff->{arglist};
my $command = shift @pargs;
my $command = $self->{pbot}->{interpreter}->shift_arg($arglist);
return "Usage: antispam <command>, where commands are: list/show, add, remove, set, unset" if not defined $command;
@ -91,7 +91,7 @@ sub antispam_cmd {
return $text;
}
when ("set") {
my ($namespace, $keyword, $flag, $value) = $self->{pbot}->{interpreter}->split_args(\@pargs, 4);
my ($namespace, $keyword, $flag, $value) = $self->{pbot}->{interpreter}->split_args($arglist, 4);
return "Usage: antispam set <namespace> <regex> [flag] [value]" if not defined $namespace or not defined $keyword;
if (not exists $self->{keywords}->hash->{$namespace}) {
@ -132,7 +132,7 @@ sub antispam_cmd {
return "Flag set.";
}
when ("unset") {
my ($namespace, $keyword, $flag) = $self->{pbot}->{interpreter}->split_args(\@pargs, 3);
my ($namespace, $keyword, $flag) = $self->{pbot}->{interpreter}->split_args($arglist, 3);
return "Usage: antispam unset <namespace> <regex> <flag>" if not defined $namespace or not defined $keyword or not defined $flag;
if (not exists $self->{keywords}->hash->{$namespace}) {
@ -152,7 +152,7 @@ sub antispam_cmd {
return "Flag unset.";
}
when ("add") {
my ($namespace, $keyword) = $self->{pbot}->{interpreter}->split_args(\@pargs, 2);
my ($namespace, $keyword) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
return "Usage: antispam add <namespace> <regex>" if not defined $namespace or not defined $keyword;
$self->{keywords}->hash->{$namespace}->{$keyword}->{owner} = "$nick!$user\@$host";
$self->{keywords}->hash->{$namespace}->{$keyword}->{created_on} = gettimeofday;
@ -160,7 +160,7 @@ sub antispam_cmd {
return "/say Added `$keyword`.";
}
when ("remove") {
my ($namespace, $keyword) = $self->{pbot}->{interpreter}->split_args(\@pargs, 2);
my ($namespace, $keyword) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
return "Usage: antispam remove <namespace> <regex>" if not defined $namespace or not defined $keyword;
if(not defined $self->{keywords}->hash->{$namespace}) {

View File

@ -170,15 +170,17 @@ sub check_blacklist {
}
sub blacklist {
my ($self, $from, $nick, $user, $host, $arguments) = @_;
$arguments = lc $arguments;
my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($command, $args) = split /\s+/, $arguments, 2;
my $arglist = $stuff->{arglist};
$self->{pbot}->{interpreter}->lc_args($arglist);
my $command = $self->{pbot}->{interpreter}->shift_arg($arglist);
return "Usage: blacklist <command>, where commands are: list/show, add, remove" if not defined $command;
given($command) {
when($_ eq "list" or $_ eq "show") {
given ($command) {
when ($_ eq "list" or $_ eq "show") {
my $text = "Blacklist:\n";
my $entries = 0;
foreach my $channel (sort keys %{ $self->{blacklist} }) {
@ -195,8 +197,8 @@ sub blacklist {
$text .= "none" if $entries == 0;
return "/msg $nick $text";
}
when("add") {
my ($mask, $channel) = split /\s+/, $args, 2;
when ("add") {
my ($mask, $channel) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
return "Usage: blacklist add <hostmask regex> [channel]" if not defined $mask;
$channel = '.*' if not defined $channel;
@ -205,8 +207,8 @@ sub blacklist {
$self->add($channel, $mask);
return "/say $mask blacklisted in channel $channel";
}
when("remove") {
my ($mask, $channel) = split /\s+/, $args, 2;
when ("remove") {
my ($mask, $channel) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
return "Usage: blacklist remove <hostmask regex> [channel]" if not defined $mask;
$channel = '.*' if not defined $channel;

View File

@ -72,7 +72,7 @@ sub in_channel {
return $usage;
}
my ($channel, $command) = split / /, $arguments, 2;
my ($channel, $command) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
return $usage if not defined $channel or not defined $command;
$stuff->{admin_channel_override} = $channel;
@ -112,9 +112,9 @@ sub logout {
sub adminadd {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($name, $channel, $hostmask, $level, $password) = split /\s+/, $arguments, 5;
my ($name, $channel, $hostmask, $level, $password) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 5);
if(not defined $name or not defined $channel or not defined $hostmask or not defined $level
or not defined $password) {
@ -139,9 +139,9 @@ sub adminadd {
sub adminrem {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($channel, $hostmask) = split /\s+/, $arguments, 2;
my ($channel, $hostmask) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
if(not defined $channel or not defined $hostmask) {
return "/msg $nick Usage: adminrem <channel> <hostmask/name>";
@ -172,8 +172,8 @@ sub adminrem {
sub adminset {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($channel, $hostmask, $key, $value) = split /\s+/, $arguments, 4 if defined $arguments;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($channel, $hostmask, $key, $value) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 4);
if(not defined $channel or not defined $hostmask) {
return "Usage: adminset <channel> <hostmask/name> [key] [value]";
@ -219,8 +219,8 @@ sub adminset {
sub adminunset {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($channel, $hostmask, $key) = split /\s+/, $arguments, 3 if defined $arguments;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($channel, $hostmask, $key) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
if(not defined $channel or not defined $hostmask) {
return "Usage: adminunset <channel> <hostmask/name> <key>";
@ -250,7 +250,7 @@ sub join_channel {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
foreach my $channel (split /\s+/, $arguments) {
foreach my $channel (split /[\s+,]/, $arguments) {
$self->{pbot}->{logger}->log("$nick!$user\@$host made me join $channel\n");
$self->{pbot}->{chanops}->join_channel($channel);
}
@ -264,7 +264,7 @@ sub part_channel {
$arguments = $from if not $arguments;
foreach my $channel (split /\s+/, $arguments) {
foreach my $channel (split /[\s+,]/, $arguments) {
$self->{pbot}->{logger}->log("$nick!$user\@$host made me part $channel\n");
$self->{pbot}->{chanops}->part_channel($channel);
}

View File

@ -49,7 +49,7 @@ sub initialize {
sub ban_user {
my $self = shift;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($target, $channel, $length) = split(/\s+/, $arguments, 3);
my ($target, $channel, $length) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
$channel = '' if not defined $channel;
$length = '' if not defined $length;
@ -114,7 +114,7 @@ sub unban_user {
return "";
}
my ($target, $channel, $immediately) = split /\s+/, $arguments;
my ($target, $channel, $immediately) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
if (defined $target and defined $channel and $channel !~ /^#/) {
my $temp = $target;
@ -152,7 +152,7 @@ sub unban_user {
sub mute_user {
my $self = shift;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($target, $channel, $length) = split(/\s+/, $arguments, 3);
my ($target, $channel, $length) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
if (not defined $from) {
$self->{pbot}->{logger}->log("Command missing ~from parameter!\n");
@ -222,7 +222,7 @@ sub unmute_user {
return "";
}
my ($target, $channel, $immediately) = split /\s+/, $arguments;
my ($target, $channel, $immediately) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
if (defined $target and defined $channel and $channel !~ /^#/) {
my $temp = $target;

View File

@ -43,8 +43,8 @@ sub initialize {
}
sub set {
my ($self, $from, $nick, $user, $host, $arguments) = @_;
my ($channel, $key, $value) = split /\s+/, $arguments, 3;
my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($channel, $key, $value) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
if(not defined $channel) {
return "Usage: chanset <channel> [key [value]]";
@ -54,8 +54,8 @@ sub set {
}
sub unset {
my ($self, $from, $nick, $user, $host, $arguments) = @_;
my ($channel, $key) = split /\s+/, $arguments;
my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($channel, $key) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
if(not defined $channel or not defined $key) {
return "Usage: chanunset <channel> <key>";

View File

@ -189,7 +189,11 @@ sub levenshtein_matches {
my $length = (length($primary_index_key) > length($index)) ? length $primary_index_key : length $index;
if($distance_result / $length < $distance) {
$result .= $comma . $index;
if ($index =~ / /) {
$result .= $comma . "\"$index\"";
} else {
$result .= $comma . $index;
}
$comma = ", ";
}
}
@ -220,7 +224,11 @@ sub levenshtein_matches {
$header = "" if $last_header eq $header;
$last_header = $header;
$comma = '; ' if $comma ne '' and $header ne '';
$result .= $comma . $header . $index2;
if ($index2 =~ / /) {
$result .= $comma . $header . "\"$index2\"";
} else {
$result .= $comma . $header . $index2;
}
$comma = ", ";
}
}

View File

@ -20,7 +20,6 @@ use POSIX qw(strftime);
use Storable;
use PBot::Utils::SafeFilename;
use PBot::Utils::ValidateString;
sub new {
if(ref($_[1]) eq 'HASH') {
@ -100,7 +99,7 @@ sub initialize {
sub call_factoid {
my $self = shift;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($chan, $keyword, $args) = split /\s+/, $arguments, 3;
my ($chan, $keyword, $args) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
if(not defined $chan or not defined $keyword) {
return "Usage: fact <channel> <keyword> [arguments]";
@ -171,7 +170,9 @@ sub log_factoid {
sub find_factoid_with_optional_channel {
my ($self, $from, $arguments, $command, $usage, $explicit, $exact_channel) = @_;
my ($from_chan, $from_trigger, $remaining_args) = split /\s+/, $arguments, 3;
my $arglist = $self->{pbot}->{interpreter}->make_args($arguments);
my ($from_chan, $from_trigger, $remaining_args) = $self->{pbot}->{interpreter}->split_args($arglist, 3);
if (not defined $from_chan or (not defined $from_chan and not defined $from_trigger)) {
return "Usage: $command [channel] <keyword>" if not $usage;
@ -192,8 +193,8 @@ sub find_factoid_with_optional_channel {
# not a channel or global, so must be a keyword
my $keyword = $from_chan;
$from_chan = $from;
$remaining_args = $from_trigger . (length $remaining_args ? " $remaining_args" : "");
$from_trigger = $keyword;
(undef, $remaining_args) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
}
}
@ -326,8 +327,7 @@ sub list_undo_history {
}
sub factundo {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($self, $from, $nick, $user, $host, $arguments, $stuff) = @_;
my $usage = "Usage: factundo [-l [N]] [-r N] [channel] <keyword> (-l list undo history, optionally starting from N; -r jump to revision N)";
@ -348,6 +348,7 @@ sub factundo {
return $usage if not @$args;
$arguments = join ' ', @$args;
my $arglist = $self->{pbot}->{interpreter}->make_args($arguments);
my ($channel, $trigger) = $self->find_factoid_with_optional_channel($from, $arguments, 'factundo', undef, 1, 1);
my $deleted;
@ -355,7 +356,7 @@ sub factundo {
if (not defined $trigger) {
# factoid not found or some error, try to continue and load undo file if it exists
$deleted = 1;
($channel, $trigger) = split /\s+/, $arguments, 2;
($channel, $trigger) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
if (not defined $trigger) {
$trigger = $channel;
$channel = $from;
@ -519,19 +520,16 @@ sub factset {
my $self = shift;
my ($from, $nick, $user, $host, $args) = @_;
$args = validate_string($args);
my ($channel, $trigger, $arguments) = $self->find_factoid_with_optional_channel($from, $args, 'factset', 'Usage: factset [channel] <factoid> [key [value]]', 1);
return $channel if not defined $trigger; # if $trigger is not defined, $channel is an error message
my ($key, $value) = split /\s+/, $arguments, 2;
my $arglist = $self->{pbot}->{interpreter}->make_args($arguments);
my ($key, $value) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
$channel = '.*' if $channel !~ /^#/;
my ($owner_channel, $owner_trigger) = $self->{pbot}->{factoids}->find_factoid($channel, $trigger, undef, 1, 1);
my $admininfo;
if (defined $owner_channel) {
$admininfo = $self->{pbot}->{admins}->loggedin($owner_channel, "$nick!$user\@$host");
} else {
@ -600,9 +598,12 @@ sub factunset {
my $usage = 'Usage: factunset [channel] <factoid> <key>';
my ($channel, $trigger, $key) = $self->find_factoid_with_optional_channel($from, $args, 'factset', $usage, 1);
my ($channel, $trigger, $arguments) = $self->find_factoid_with_optional_channel($from, $args, 'factunset', $usage, 1);
return $channel if not defined $trigger; # if $trigger is not defined, $channel is an error message
my $arglist = $self->{pbot}->{interpreter}->make_args($arguments);
my ($key) = $self->{pbot}->{interpreter}->split_args($arglist, 1);
return $usage if not length $key;
my ($owner_channel, $owner_trigger) = $self->{pbot}->{factoids}->find_factoid($channel, $trigger, undef, 1, 1);
@ -731,9 +732,8 @@ sub list {
sub factmove {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
$arguments = validate_string($arguments);
my ($src_channel, $source, $target_channel, $target) = split /\s+/, $arguments, 5 if length $arguments;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($src_channel, $source, $target_channel, $target) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 5);
my $usage = "Usage: factmove <source channel> <source factoid> <target channel/factoid> [target factoid]";
@ -821,11 +821,10 @@ sub factmove {
sub factalias {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
$arguments = validate_string($arguments);
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($chan, $alias, $command) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
my ($chan, $alias, $command) = split /\s+/, $arguments, 3 if defined $arguments;
if (defined $chan and not ($chan eq '.*' or $chan =~ m/^#/)) {
# $chan doesn't look like a channel, so shift everything right
# and replace $chan with $from
@ -838,6 +837,8 @@ sub factalias {
$chan = $from;
}
$chan = '.*' if $chan !~ /^#/;
if (not length $alias or not length $command) {
return "Usage: factalias [channel] <keyword> <command>";
}
@ -878,7 +879,6 @@ sub add_regex {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
$arguments = validate_string($arguments);
my ($keyword, $text) = $arguments =~ /^(.*?)\s+(.*)$/ if defined $arguments;
$from = '.*' if not defined $from or $from !~ /^#/;
@ -911,16 +911,19 @@ sub add_regex {
sub factadd {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($from_chan, $keyword, $text);
$arguments = validate_string($arguments);
my @arglist = @{$stuff->{arglist}};
if (defined $arguments) {
if ($arguments =~ /^(#\S+|global|\.\*)\s+(\S+)\s+(?:is\s+)?(.*)$/i) {
($from_chan, $keyword, $text) = ($1, $2, $3);
} elsif ($arguments =~ /^(\S+)\s+(?:is\s+)?(.*)$/i) {
($from_chan, $keyword, $text) = ($from, $1, $2);
if (@arglist) {
if ($arglist[0] =~ m/(?:^#|^global$|^\.\*$)/i) {
splice @arglist, 2, 1 if lc $arglist[2] eq 'is';
($from_chan, $keyword, $text) = $self->{pbot}->{interpreter}->split_args(\@arglist, 3);
} else {
$from_chan = $from;
splice @arglist, 1, 1 if lc $arglist[1] eq 'is';
($keyword, $text) = $self->{pbot}->{interpreter}->split_args(\@arglist, 2);
}
}
@ -965,10 +968,10 @@ sub factadd {
sub factrem {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
my ($from_chan, $from_trig) = split /\s+/, $arguments;
my ($from_chan, $from_trig) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
if (not defined $from_trig) {
$from_trig = $from_chan;
@ -1038,10 +1041,10 @@ sub histogram {
sub factshow {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
my ($chan, $trig) = split /\s+/, $arguments;
my ($chan, $trig) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
if (not defined $trig) {
$trig = $chan;
@ -1093,7 +1096,8 @@ sub factlog {
if (not defined $trigger) {
# factoid not found or some error, try to continue and load factlog file if it exists
($channel, $trigger) = split /\s+/, "@$args", 2;
my $arglist = $self->{pbot}->{interpreter}->make_args("@$args");
($channel, $trigger) = $self->{pbot}->{interpreter}->split_args($arglist, 2);
if (not defined $trigger) {
$trigger = $channel;
$channel = $from;
@ -1138,10 +1142,10 @@ sub factlog {
sub factinfo {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
my ($chan, $trig) = split /\s+/, $arguments;
my ($chan, $trig) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
if (not defined $trig) {
$trig = $chan;
@ -1178,13 +1182,13 @@ sub factinfo {
sub top20 {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
my %hash = ();
my $text = "";
my $i = 0;
my ($channel, $args) = split /\s+/, $arguments, 2 if defined $arguments;
my ($channel, $args) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
if(not defined $channel) {
return "Usage: top20 <channel> [nick or 'recent']";
@ -1366,7 +1370,11 @@ sub factfind {
$text .= $chan eq '.*' ? "[global channel] " : "[$chan] ";
$last_chan = $chan;
}
$text .= "$trigger ";
if ($trigger =~ / /) {
$text .= "\"$trigger\" ";
} else {
$text .= "$trigger ";
}
$last_trigger = $trigger;
}
}
@ -1393,8 +1401,6 @@ sub factchange {
my $factoids = $self->{pbot}->{factoids}->{factoids}->hash;
my ($channel, $trigger, $keyword, $delim, $tochange, $changeto, $modifier);
$arguments = validate_string($arguments);
my $needs_disambig;
if (defined $arguments) {

View File

@ -46,11 +46,11 @@ sub initialize {
sub ignore_user {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
return "/msg $nick Usage: ignore nick!user\@host [channel] [timeout]" if not defined $arguments;
my ($target, $channel, $length) = split /\s+/, $arguments, 3;
my ($target, $channel, $length) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
if(not defined $target) {
return "/msg $nick Usage: ignore host [channel] [timeout]";
@ -95,8 +95,8 @@ sub ignore_user {
sub unignore_user {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($target, $channel) = split /\s+/, $arguments if defined $arguments;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($target, $channel) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
if(not defined $target) {
return "/msg $nick Usage: unignore host [channel]";

View File

@ -206,8 +206,12 @@ sub interpret {
return undef;
}
if ($stuff->{command} =~ /^tell\s+(\p{PosixGraph}{1,20})\s+about\s+(.*?)\s+(.*)$/is) {
($keyword, $arguments, $stuff->{nickoverride}) = ($2, $3, $1);
my $cmdlist = $self->make_args($stuff->{command});
if ($self->arglist_size($cmdlist) >= 4 and lc $cmdlist->[0] eq 'tell' and lc $cmdlist->[2] eq 'about') {
$stuff->{nickoverride} = $cmdlist->[1];
($keyword, $arguments) = $self->split_args($cmdlist, 2, 3);
$arguments = '' if not defined $arguments;
my $similar = $self->{pbot}->{nicklist}->is_present_similar($stuff->{from}, $stuff->{nickoverride});
if ($similar) {
$stuff->{nickoverride} = $similar;
@ -216,25 +220,15 @@ sub interpret {
delete $stuff->{nickoverride};
delete $stuff->{force_nickoverride};
}
} elsif ($stuff->{command} =~ /^tell\s+(\p{PosixGraph}{1,20})\s+about\s+(.*)$/is) {
($keyword, $stuff->{nickoverride}) = ($2, $1);
my $similar = $self->{pbot}->{nicklist}->is_present_similar($stuff->{from}, $stuff->{nickoverride});
if ($similar) {
$stuff->{nickoverride} = $similar;
$stuff->{force_nickoverride} = 1;
} else {
delete $stuff->{nickoverride};
delete $stuff->{force_nickoverride};
}
} elsif ($stuff->{command} =~ /^(.*?)\s+(.*)$/s) {
($keyword, $arguments) = ($1, $2);
} else {
$keyword = $stuff->{command};
($keyword, $arguments) = $self->split_args($cmdlist, 2);
$arguments = "" if not defined $arguments;
}
if (length $keyword > 30) {
$keyword = substr($keyword, 0, 30);
$self->{pbot}->{logger}->log("Truncating keyword to 30 chars: $keyword\n");
# FIXME: make this a registry item
if (length $keyword > 128) {
$keyword = substr($keyword, 0, 128);
$self->{pbot}->{logger}->log("Truncating keyword to 128 chars: $keyword\n");
}
# parse out a substituted command
@ -318,16 +312,30 @@ sub interpret {
# unescape any escaped pipes
$arguments =~ s/\\\|\s*\{/| {/g if defined $arguments;
$arguments = validate_string($arguments);
# set arguments as a plain string
$stuff->{arguments} = $arguments;
# set arguments as a positional array
my @args = split / /, $arguments;
my @pargs;
# set arguments as an array
$stuff->{arglist} = $self->make_args($arguments);
# handle this shit
return $self->SUPER::execute_all($stuff);
}
# creates an array of arguments from a string
sub make_args {
my ($self, $string) = @_;
my @args = split / /, $string;
my @arglist;
my @arglist_quotes;
while (@args) {
my $arg = shift @args;
# is this a quoted argument?
if ($arg =~ /^["']/) {
my $string = $arg;
if (@args) {
@ -336,43 +344,73 @@ sub interpret {
}
my ($extracted, $rest) = extract_quotelike $string;
if (defined $extracted) {
# preserve quotes for $rest in split_args()
push @arglist_quotes, $extracted;
# strip quote characters
$extracted =~ s/^(.)//;
$extracted =~ s/$1$//;
push @pargs, $extracted;
push @arglist, $extracted;
$rest =~ s/^ //;
@args = split / /, $rest;
} else {
# mismatched quotes, shove the remainder as the last positional argument
push @pargs, $rest;
push @arglist, $rest;
last;
}
} else {
push @pargs, $arg;
push @arglist, $arg;
push @arglist_quotes, $arg;
}
}
$stuff->{argumentspos} = \@pargs;
# copy original args with quotes intact to end of arglist
push @arglist, @arglist_quotes;
return \@arglist;
}
return $self->SUPER::execute_all($stuff);
# returns size of array of arguments
sub arglist_size {
my ($self, $args) = @_;
return @$args / 2;
}
# shifts first argument off array of arguments
sub shift_arg {
my ($self, $args) = @_;
splice @$args, @$args / 2, 1; # remove original quoted argument
return shift @$args;
}
# splits array of arguments into array with overflow arguments filling up last position
# split_args(qw/dog cat bird hamster/, 3) => ("dog", "cat", "bird hamster")
sub split_args {
my ($self, $args, $count) = @_;
my ($self, $args, $count, $offset) = @_;
my @result;
while (--$count) {
my $arg = shift @$args;
push @result, $arg;
}
my $max = $self->arglist_size($args);
my $rest = join ' ', @$args;
push @result, $rest;
my $i = $offset // 0;
do {
my $arg = $args->[$i++];
push @result, $arg;
} while (--$count > 1 and $i < $max);
# get rest from 2nd half of arglist, which contains original quotes
my $rest = join ' ', @$args[@$args / 2 + $i .. @$args - 1];
push @result, $rest if length $rest;
return @result;
}
# lowercases array of arguments
sub lc_args {
my ($self, $args) = @_;
for (my $i = 0; $i < @$args; $i++) {
$args->[$i] = lc $args->[$i];
}
}
sub truncate_result {
my ($self, $from, $nick, $text, $original_result, $result, $paste) = @_;
my $max_msg_len = $self->{pbot}->{registry}->get_value('irc', 'max_msg_len');

View File

@ -42,8 +42,8 @@ sub initialize {
sub regset {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($section, $item, $key, $value) = split /\s+/, $arguments, 4 if defined $arguments;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($section, $item, $key, $value) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 4);
if(not defined $section or not defined $item) {
return "Usage: regset <section> <item> [key [value]]";
@ -57,8 +57,8 @@ sub regset {
sub regunset {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($section, $item, $key) = split /\s+/, $arguments, 3 if defined $arguments;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($section, $item, $key) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
if(not defined $section or not defined $item or not defined $key) {
return "Usage: regunset <section> <item> <key>"
@ -69,8 +69,8 @@ sub regunset {
sub regadd {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($section, $item, $value) = split /\s+/, $arguments, 3 if defined $arguments;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($section, $item, $value) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 3);
if(not defined $section or not defined $item or not defined $value) {
return "Usage: regadd <section> <item> <value>";
@ -84,8 +84,8 @@ sub regadd {
sub regrem {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($section, $item) = split /\s+/, $arguments if defined $arguments;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my ($section, $item) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
if(not defined $section or not defined $item) {
return "Usage: regrem <section> <item>";
@ -106,10 +106,10 @@ sub regrem {
sub regshow {
my $self = shift;
my ($from, $nick, $user, $host, $arguments) = @_;
my ($from, $nick, $user, $host, $arguments, $stuff) = @_;
my $registry = $self->{pbot}->{registry}->{registry}->hash;
my ($section, $item) = split /\s+/, $arguments if defined $arguments;
my ($section, $item) = $self->{pbot}->{interpreter}->split_args($stuff->{arglist}, 2);
if(not defined $section or not defined $item) {
return "Usage: regshow <section> <item>";