summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@thenautilus.net>2021-06-04 16:17:09 +0100
committerdakkar <dakkar@thenautilus.net>2021-06-04 16:17:09 +0100
commit63c846df17c3d2553faaec3a95cebf8b9ba1e709 (patch)
tree280bfaf6952b86b6fd331320ab987ddd3a7b38ea
parenttrack who's an op (diff)
downloadraku-boha-63c846df17c3d2553faaec3a95cebf8b9ba1e709.tar.gz
raku-boha-63c846df17c3d2553faaec3a95cebf8b9ba1e709.tar.bz2
raku-boha-63c846df17c3d2553faaec3a95cebf8b9ba1e709.zip
op tracking that actually works
-rw-r--r--boha.raku103
1 files changed, 55 insertions, 48 deletions
diff --git a/boha.raku b/boha.raku
index 97240ba..28b7263 100644
--- a/boha.raku
+++ b/boha.raku
@@ -7,85 +7,92 @@ my $config = from-toml(
file => (%*ENV<BOHA_CONFIG_FILE> // $?FILE.IO.sibling('boha.toml').Str)
);
-role TracksOps does IRC::Client::Plugin {
- has %!nick-cache;
- has $!waiting-for-names = False;
-
- method !check-op($e) {
- return Promise.broken('not a channel message') unless $e.?channel;
- # if we already know whether that's an op, the cache will
- # contain a kept promise; if we don't, we have to wait for the
- # next 353, so we set and return a planned promise
- return %!nick-cache{$e.channel}{$e.nick} //= Promise.new();
+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($e) {
+ 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 ~~ / ^ $<sigil> = [ '@' | '+' ]? $<nick> = [ .+ ] $ /;
- # I'm not sure what `+` means
- my $is-op = $user<sigil> eq '@';
-
- my $value := %!nick-cache{$channel}{$user<nick>};
- if $value ~~ Promise && $value.status ~~ Planned {
- # someone called check-op before we saw this nick:
- # keep the promise
- $value.keep($is-op);
- }
- else {
- # either this nick changed state, or nobody asked
- # about it before: set a kept promise
- $value = Promise.kept($is-op);
- }
+ self!set-user-mode(
+ $server, $channel,
+ $user<nick>,
+ $user<sigil> eq '@'
+ );
}
- $!waiting-for-names = False;
-
return $.NEXT;
}
- method irc-join($e) {
- # someone (maybe us) joined the channel: update our ops map
- #
- # maybe we should do this every few seconds anyway…
- Promise.in(5).then: {
- unless ($!waiting-for-names) {
- $e.irc.send-cmd('NAMES', $e.channel, :server($e.server));
- $!waiting-for-names = True;
- }
- };
+ 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 TracksOps {
+class Boha1 does IRC::Client::Plugin {
+ has TrackOps $.ops handles <is-op>;
+
# irc-addressed for in-channel messages
# irc-privmsg-me for direct messages
method irc-addressed($e) {
- return self!check-op($e).then: sub ($promise) {
- if ($promise.status ~~ Broken) {
- # not a channel message?
- return Nil;
- }
- if (so $promise.result) {
- return "you're an op";
+ 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 "you're a normal user";
+ 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<server>),
channels => $config<channels>.map(*.<name>),
:debug,
:plugins(
- Boha1.new,
+ $ops,
+ $boha,
),
);