diff options
-rw-r--r-- | Plugin/Admin.pm | 183 | ||||
-rw-r--r-- | Plugin/Echo.pm | 2 | ||||
-rw-r--r-- | Plugin/Map.pm | 2 | ||||
-rw-r--r-- | Plugin/Ping.pm | 2 | ||||
-rw-r--r-- | Plugin/Source.pm | 26 | ||||
-rw-r--r-- | Plugin/Timezone.pm | 2 | ||||
-rw-r--r-- | bot.conf.example | 3 | ||||
-rw-r--r-- | config_file.pm | 3 | ||||
-rwxr-xr-x | idalius.pl | 148 |
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 = ( @@ -31,6 +31,8 @@ my @plugin_list = plugins("dummy", \®ister_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; } |