aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Plugin/Admin.pm183
-rw-r--r--Plugin/Echo.pm2
-rw-r--r--Plugin/Map.pm2
-rw-r--r--Plugin/Ping.pm2
-rw-r--r--Plugin/Source.pm26
-rw-r--r--Plugin/Timezone.pm2
-rw-r--r--bot.conf.example3
-rw-r--r--config_file.pm3
-rwxr-xr-xidalius.pl148
9 files changed, 244 insertions, 127 deletions
diff --git a/Plugin/Admin.pm b/Plugin/Admin.pm
new file mode 100644
index 0000000..2a2a691
--- /dev/null
+++ b/Plugin/Admin.pm
@@ -0,0 +1,183 @@
+#!/usr/bin/env perl
+
+package Plugin::Admin;
+
+use strict;
+use warnings;
+
+my %config;
+
+sub configure {
+ my $self = $_[0];
+ my $cmdref = $_[1];
+ my $cref = $_[2];
+ %config = %$cref;
+
+ $cmdref->("say", sub { $self->say(@_); } );
+ $cmdref->("action", sub { $self->action(@_); } );
+
+ $cmdref->("nick", sub { $self->nick(@_); } );
+ $cmdref->("join", sub { $self->join_channel(@_); } );
+ $cmdref->("part", sub { $self->part(@_); } );
+ $cmdref->("mode", sub { $self->mode(@_); } );
+ $cmdref->("kick", sub { $self->kick(@_); } );
+ $cmdref->("topic", sub { $self->topic(@_); } );
+ $cmdref->("reconnect", sub { $self->reconnect(@_); } );
+
+ $cmdref->("ignore", sub { $self->ignore(@_); } );
+ $cmdref->("don't ignore", sub { $self->do_not_ignore(@_); } );
+ $cmdref->("who are you ignoring?", sub { $self->dump_ignore(@_); } );
+
+ return $self;
+}
+
+sub is_admin {
+ my $who = shift;
+ my $is_admin = grep {$_ eq $who} @{$config{admins}};
+ if (!$is_admin) {
+ # Uhh log this rather than print
+ print "$who isn't an admin, but tried to use a command";
+ }
+ return $is_admin;
+}
+
+sub nick {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+ return "Syntax: nick <new nick>" unless @arguments == 1;
+
+ $irc->yield(nick => $arguments[0]);
+}
+
+sub say {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+ return "Syntax: say <channel> <msg>" unless @arguments >= 2;
+
+ # Strip nick/channel from message
+ $rest =~ s/^(.*?\s)//;
+
+ $irc->yield(privmsg => $arguments[0] => $rest);
+}
+
+sub action {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+ return "Syntax: action <channel> <action text>" unless @arguments >= 2;
+
+ # Strip nick/channel from message
+ $rest =~ s/^(.*?\s)//;
+
+ $irc->yield(ctcp => $arguments[0] => "ACTION $rest");
+}
+
+sub join_channel {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+ return "Syntax: join <channel1> [channel2 ...]" unless @arguments >= 1;
+
+ $irc->yield(join => $_) for @arguments;
+}
+
+sub part {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+ return "Syntax: part <channel1> [channel2 ...] [partmsg]" unless @arguments >= 1;
+
+ my $nick = (split /!/, $who)[0];
+ my ($chan_str, $reason) = split /\s+(?!#)/, $rest, 2;
+ my @channels = split /\s+/, $chan_str;
+ $reason = "Commanded by $nick" unless $reason;
+ $irc->yield(part => @channels => $reason);
+}
+
+sub mode {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+ return "Syntax: mode <everything>" unless @arguments > 0;
+
+ # FIXME should use $where if it's a channel (?)
+ $irc->yield(mode => $rest);
+}
+
+sub kick {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+ return "Syntax: kick <channel> <nick> [reason]" unless @arguments >= 2;
+
+ # FIXME should use $where if it's a channel (?)
+ my ($channel, $kickee, undef, $reason) = $rest =~ /^(\S+)\s(\S+)((?:\s)(.*))?$/;
+ if ($channel and $kickee) {
+ my $nick = (split /!/, $who)[0];
+ $reason = "Requested by $nick" unless $reason;
+ $irc->yield(kick => $channel => $kickee => $reason);
+ }
+}
+
+sub topic {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+ return "Syntax: topic <new topic>" unless @arguments >= 2;
+
+ # Strip nick/channel from message
+ $rest =~ s/^(.*?\s)//;
+
+ # FIXME use $where if it's a channel
+ $irc->yield(topic => $arguments[0] => $rest);
+}
+
+sub reconnect {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+
+ my $reason = $rest;
+ $irc->yield(quit => $reason);
+}
+
+sub ignore {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+ return "Syntax: ignore <nick>" unless @arguments == 1;
+
+ push @{$config{ignore}}, $arguments[0];
+
+ return "Ignoring $arguments[0]";
+}
+
+sub do_not_ignore {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return unless is_admin($who);
+ return "Syntax: don't ignore <nick>" unless @arguments == 1;
+
+ my $target = $arguments[0];
+
+ if (grep { $_ eq $target} @{$config{ignore}}) {
+ @{$config{ignore}} = grep { $_ ne $target } @{$config{ignore}};
+ return "No longer ignoring $target.";
+ } else {
+ return "I wasn't ignoring $target anyway.";
+ }
+}
+
+sub dump_ignore {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+
+ return "Syntax: who are you ignoring?" unless @arguments == 0;
+
+ # FIXME special case for empty ignore
+ return "I am ignoring: " . join ", ", @{$config{ignore}};
+}
+
+
+1;
diff --git a/Plugin/Echo.pm b/Plugin/Echo.pm
index 9b23af8..5f2c53a 100644
--- a/Plugin/Echo.pm
+++ b/Plugin/Echo.pm
@@ -19,7 +19,7 @@ sub configure {
}
sub echo {
- my ($self, $logger, $who, $where, $rest, @arguments) = @_;
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
return $rest;
}
diff --git a/Plugin/Map.pm b/Plugin/Map.pm
index 9ca8cef..4bd65a6 100644
--- a/Plugin/Map.pm
+++ b/Plugin/Map.pm
@@ -22,7 +22,7 @@ sub configure {
}
sub map {
- my ($self, $logger, $who, $where, $rest, @arguments) = @_;
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
my ($command, $subjects) = ($rest =~ /^(.+?)\s+(.*)$/);
return "[]" unless $subjects;
diff --git a/Plugin/Ping.pm b/Plugin/Ping.pm
index d935512..de6fd8e 100644
--- a/Plugin/Ping.pm
+++ b/Plugin/Ping.pm
@@ -17,7 +17,7 @@ sub configure {
}
sub ping {
- my ($self, $logger, $who, $where, $rest, @arguments) = @_;
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
my $nick = (split /!/, $who)[0];
return "$nick: pong";
}
diff --git a/Plugin/Source.pm b/Plugin/Source.pm
new file mode 100644
index 0000000..940fc2f
--- /dev/null
+++ b/Plugin/Source.pm
@@ -0,0 +1,26 @@
+#!/usr/bin/env perl
+
+package Plugin::Source;
+
+use strict;
+use warnings;
+
+my %config;
+
+sub configure {
+ my $self = shift;
+ my $cmdref = shift;
+ my @source_commands = ("guts", "help", "source");
+ $cmdref->($_, sub { $self->source(@_); }) for @source_commands;
+ return $self;
+}
+
+sub source {
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
+ my @urls = (
+ "https://git.nah.nz/idalius/",
+ "https://gitlab.com/dphillips/idalius");
+ my $help_message = "My guts can be browsed at: ";
+ return $help_message . join " ", @urls;
+}
+1;
diff --git a/Plugin/Timezone.pm b/Plugin/Timezone.pm
index a536ed6..eb953a1 100644
--- a/Plugin/Timezone.pm
+++ b/Plugin/Timezone.pm
@@ -21,7 +21,7 @@ sub configure {
}
sub time {
- my ($self, $logger, $who, $where, $rest, @arguments) = @_;
+ my ($self, $irc, $logger, $who, $where, $rest, @arguments) = @_;
my $requester = (split /!/, $who)[0];
my @known_zones = (keys %{$config{timezone}});
diff --git a/bot.conf.example b/bot.conf.example
index d874777..428b5eb 100644
--- a/bot.conf.example
+++ b/bot.conf.example
@@ -4,6 +4,8 @@ ircname = a bot
server = irc.example.net
port = 6667
usessl = 1
+sslcert = foo.crt
+sslkey = foo.key
channels = #saxtalk,#bot
ignore = trumpetbot,abusiveuser
password = pleffquiffle
@@ -13,6 +15,7 @@ quit_msg = "Goodbye!"
user = nobody
group = nobody
triggers = 'sa+x' => '🎷 ', 'trumpet' => '🎺 ', 'snake' => '🐍 '
+prefix_nick = 1
prefix = %
antiflood_on = 0
diff --git a/config_file.pm b/config_file.pm
index 304338f..01991c7 100644
--- a/config_file.pm
+++ b/config_file.pm
@@ -15,6 +15,8 @@ sub parse_config
'server',
'port',
'usessl',
+ 'sslcert',
+ 'sslkey',
'password',
'must_id',
'quit_msg',
@@ -22,6 +24,7 @@ sub parse_config
'group',
'url_on',
'url_len',
+ 'prefix_nick',
'prefix',
'antiflood_on');
my @list_configs = (
diff --git a/idalius.pl b/idalius.pl
index 89c89e5..8db549f 100755
--- a/idalius.pl
+++ b/idalius.pl
@@ -31,6 +31,8 @@ my @plugin_list = plugins("dummy", \&register_command, \%config, \&run_command);
# New PoCo-IRC object
my $irc = POE::Component::IRC->spawn(
UseSSL => $config{usessl},
+ SSLCert => $config{sslcert},
+ SSLKey => $config{sslkey},
nick => $config{nick},
ircname => $config{ircname},
port => $config{port},
@@ -85,13 +87,22 @@ sub register_command {
sub run_command {
my ($command_string, $who, $where) = @_;
my @arguments;
- my ($command, $rest) = split /\s+/, $command_string, 2;
- @arguments = split /\s+/, $rest if $rest;
- if ($commands{$command}) {
- return ($commands{$command})->(\&log_info, $who, $where, $rest, @arguments);
- } else {
- return "No such command \"$command\"";
+ my $command_verbatim;
+ my $command;
+
+ for my $c (keys %commands) {
+ if (($command_verbatim) = $command_string =~ m/^(\Q$c\E( |$))/) {
+ $command = $c;
+ last;
+ }
}
+
+ return "No such command" unless $command;
+
+ my $rest = (split "\Q$command_verbatim", $command_string, 2)[1];
+ @arguments = split /\s+/, $rest if $rest;
+
+ return ($commands{$command})->($irc, \&log_info, $who, $where, $rest, @arguments);
}
sub custom_ping {
@@ -140,6 +151,7 @@ sub irc_001 {
log_info("Connected to server ", $heap->server_name());
+ $current_nick = $config{nick};
$heap->yield(join => $_) for @{$config{channels}};
$irc->delay(custom_ping => $ping_delay);
return;
@@ -179,7 +191,8 @@ sub irc_public {
return if (grep {$_ eq $nick} @{$config{ignore}});
my $stripped_what = strip_color(strip_formatting($what));
- if ($stripped_what =~ s/^$config{prefix}//) {
+ if ($config{prefix_nick} && $stripped_what =~ s/^\Q$current_nick\E[:,]\s+//g ||
+ $stripped_what =~ s/^$config{prefix}//) {
$output = run_command($stripped_what, $who, $where);
$irc->yield(privmsg => $where => $output) if $output;
strike_add($nick, $channel) if $output;
@@ -210,122 +223,11 @@ sub irc_msg {
return;
}
return unless $is_admin;
- # FIXME this needs tidying. Some of this can be factored out, surely.
- if ($what =~ /^nick\s/) {
- my ($newnick) = $what =~ /^nick\s+(\S+)$/;
- if ($newnick) {
- $irc->yield(nick => $newnick);
- $irc->yield(privmsg => $nick => "Requested.");
- } else {
- $irc->yield(privmsg => $nick => "Syntax: nick <nick>");
- }
- }
- if ($what =~ /^ignore\s/) {
- my ($target) = $what =~ /^ignore\s+(\S+)$/;
- if ($target) {
- push @{$config{ignore}}, $target;
- $irc->yield(privmsg => $nick => "Ignoring $target.");
- } else {
- $irc->yield(privmsg => $nick => "Syntax: ignore <nick>");
- }
- }
- if ($what =~ /^don't ignore\s/) {
- my ($target) = $what =~ /^don't ignore\s+(\S+)$/;
- if ($target) {
- if (grep { $_ eq $target} @{$config{ignore}}) {
- @{$config{ignore}} = grep { $_ ne $target } @{$config{ignore}};
- $irc->yield(privmsg => $nick => "No longer ignoring $target.");
- } else {
- $irc->yield(privmsg => $nick => "I wasn't ignoring $target anyway.");
- }
- } else {
- $irc->yield(privmsg => $nick => "Syntax: don't ignore <nick>");
- }
- }
- if ($what =~ /^part\s/) {
- my $message;
- if ($what =~ /^part(\s+(\S+))+$/m) {
- $what =~ s/^part\s+//;
- my ($chan_str, $reason) = split /\s+(?!#)/, $what, 2;
- my @channels = split /\s+/, $chan_str;
- $reason = "Commanded by $nick" unless $reason;
- $irc->yield(part => @channels => $reason);
- $irc->yield(privmsg => $nick => "Requested.");
- } else {
- $irc->yield(privmsg => $nick =>
- "Syntax: part <channel1> [channel2 ...] [partmsg]");
- }
- }
- if ($what =~ /^join\s/) {
- if ($what =~ /^join(\s+(\S+))+$/) {
- $what =~ s/^join\s+//;
- my @channels = split /\s+/, $what;
- $irc->yield(join => $_) for @channels;
- $irc->yield(privmsg => $nick => "Requested.");
- } else {
- $irc->yield(privmsg => $nick =>
- "Syntax: join <channel1> [channel2 ...]");
- }
- }
- if ($what =~ /^say\s/) {
- my ($channel, $message) = $what =~ /^say\s+(\S+)\s(.*)$/;
- if ($channel and $message) {
- $irc->yield(privmsg => $channel => $message);
- $irc->yield(privmsg => $nick => "Requested.");
- } else {
- $irc->yield(privmsg => $nick => "Syntax: say <channel> <msg>");
- }
- }
- if ($what =~ /^action\s/) {
- my ($channel, $action) = $what =~ /^action\s+(\S+)\s(.*)$/;
- if ($channel and $action) {
- $irc->yield(ctcp => $channel => "ACTION $action");
- $irc->yield(privmsg => $nick => "Requested.");
- } else {
- $irc->yield(privmsg => $nick => "Syntax: action <channel> <action text>");
- }
- }
- if ($what =~ /^topic\s/) {
- my ($channel, $topic) = $what =~ /^topic\s+(\S+)\s(.*)?$/;
- if ($channel) {
- $topic = "" unless $topic;
- $irc->yield(topic => $channel => $topic);
- $irc->yield(privmsg => $nick => "Requested.");
- } else {
- $irc->yield(privmsg => $nick => "Syntax: topic <channel> <topic>");
- }
- }
- if ($what =~ /^who are you ignoring/) {
- my $ignores = join ", ", @{$config{ignore}};
- $irc->yield(privmsg => $nick => "I am ignoring: $ignores");
- }
- if ($what =~ /^mode\s/) {
- my ($rest) = $what =~ /^mode\s+(.*)?$/;
- if ($rest) {
- $irc->yield(mode => $rest);
- $irc->yield(privmsg => $nick => "Requested.");
- } else {
- $irc->yield(privmsg => $nick => "Syntax: mode [everything]");
- }
- }
- if ($what =~ /^kick\s/) {
- my ($channel, $kickee, undef, $reason) = $what =~ /^kick\s+(\S+)\s(\S+)((?:\s)(.*))?$/;
- if ($channel and $kickee) {
- $reason = "Requested by $nick" unless $reason;
- $irc->yield(kick => $channel => $kickee => $reason);
- $irc->yield(privmsg => $nick => "Requested.");
- } else {
- $irc->yield(privmsg => $nick => "Syntax: kick <channel> <nick> [reason]");
- }
- }
- if ($what =~ /^reconnect/) {
- my ($reason) = $what =~ /^reconnect\s+(.+)$/;
- $irc->yield(privmsg => $nick => "Doing that now");
- if (!$reason) {
- $reason = $config{quit_msg};
- }
- $irc->yield(quit => $reason);
- }
+
+ my $stripped_what = strip_color(strip_formatting($what));
+ my $output = run_command($stripped_what, $who, $nick);
+ $irc->yield(privmsg => $nick => $output) if $output;
+
return;
}