summaryrefslogtreecommitdiff
path: root/boha.raku
blob: 28b7263f9ecb12093472bc36971fca22b9287a7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env rakudo 
use v6.d;
use Config::TOML;
use IRC::Client;
 
my $config = from-toml(
    file => (%*ENV<BOHA_CONFIG_FILE> // $?FILE.IO.sibling('boha.toml').Str)
);
 
class TrackOps does IRC::Client::Plugin {
    has %!is-op;
 
    multi method is-op(
        Str() $serverStr() $channelStr() $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() $serverStr() $channelStr() $nickBool $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 ~~ / ^ $<sigil> = [ '@' | '+' ]? $<nick> = [ .+ ] $ /;
 
            self!set-user-mode(
                $server, $channel,
                $user<nick>,
                $user<sigil> 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 <is-op>;
 
    # irc-addressed for in-channel messages 
    # irc-privmsg-me for direct messages 
 
    method irc-addressed($e{
        my @words = $e.text.split(/\s+/);
 
        if @words[0eq '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<server>),
    channels => $config<channels>.map(*.<name>),
    :debug,
    :plugins(
        $ops,
        $boha,
    ),
);