#!/usr/bin/env rakudo use v6.d; use Config::TOML; use IRC::Client; my $config = from-toml( file => (%*ENV // $?FILE.IO.sibling('boha.toml').Str) ); class TrackOps does IRC::Client::Plugin { has %!is-op; multi method is-op( Str() $server, Str() $channel, Str() $nick --> Bool ) { return %!is-op{$server}{$channel}{$nick}.so; } multi method is-op(IRC::Client::Message $e --> Bool) { fail 'not a channel message' unless $e.?channel; return self.is-op($e.server,$e.channel,$e.nick); } method !set-user-mode( Str() $server, Str() $channel, Str() $nick, Bool $mode ) { %!is-op{$server}{$channel}{$nick} = $mode; } # response to /NAMES method irc-n353(IRC::Client::Message $e) { my $server = $e.server; my ($my-nick,$equal,$channel,$names) = $e.args(); for $names.split(/\s+/) -> $name-str { my $user = $name-str ~~ / ^ $ = [ '@' | '+' ]? $ = [ .+ ] $ /; self!set-user-mode( $server, $channel, $user, $user eq '@' ); } return $.NEXT; } method irc-mode-channel($e) { my ($server, $channel) = $e.server, $e.channel; my $new-mode = ( $e.mode eq '+o' ?? True !! $e.mode eq '-o' ?? False !! return $.NEXT ); for $e.nicks() -> $nick { self!set-user-mode($server,$channel,$nick,$new-mode); } return $.NEXT; } } class Boha1 does IRC::Client::Plugin { has TrackOps $.ops handles ; # irc-addressed for in-channel messages # irc-privmsg-me for direct messages method irc-addressed($e) { my @words = $e.text.split(/\s+/); if @words[0] eq 'op' { my $nick = @words[1]; if self.is-op($e.server,$e.channel,$nick) { return "$nick is op"; } else { return "$nick is a normal user"; } } else { return "I don't know understand '$e.text'"; } } } my TrackOps $ops .= new; my Boha1 $boha .= new(:$ops); .run with IRC::Client.new( |($config), channels => $config.map(*.), :debug, :plugins( $ops, $boha, ), );