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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
unit class IRC::Client::Grammar::Actions;
use IRC::Client::Message;
has $.irc;
has $.server;
method TOP ($/) {
$/.make: (
$<message>ยป.made,
~( $<left-overs> // '' ),
);
}
method message ($match) {
my %args;
my $pref = $match<prefix>;
for qw/nick user host/ {
$pref{$_}.defined or next;
%args<who>{$_} = ~$pref{$_};
}
%args<who><host> = ~$pref<servername> if $pref<servername>.defined;
my $p = $match<params>;
loop {
%args<params>.append: ~$p<middle> if $p<middle>.defined;
if ( $p<trailing>.defined ) {
%args<params>.append: ~$p<trailing>;
last;
}
last unless $p<params>.defined;
$p = $p<params>;
}
my %msg-args =
command => $match<command>.uc,
args => %args<params>,
host => %args<who><host>//'',
irc => $!irc,
nick => %args<who><nick>//'',
server => $!server,
usermask => ~($match<prefix>//''),
username => %args<who><user>//'';
my $msg;
given %msg-args<command> {
when /^ $<command>=(<[0..9]>**3) $/ {
$msg = IRC::Client::Message::Numeric.new: |%msg-args;
}
when 'JOIN' {
$msg = IRC::Client::Message::Join.new:
:channel( %args<params>[0] ),
|%msg-args;
}
when 'PART' {
$msg = IRC::Client::Message::Part.new:
:channel( %args<params>[0] ),
|%msg-args;
}
when 'NOTICE' { $msg = msg-notice %args, %msg-args }
when 'MODE' { $msg = msg-mode %args, %msg-args }
when 'PING' { $msg = IRC::Client::Message::Ping.new: |%msg-args }
when 'PRIVMSG' { $msg = msg-privmsg %args, %msg-args }
when 'QUIT' { $msg = IRC::Client::Message::Quit.new: |%msg-args }
default { $msg = IRC::Client::Message::Unknown.new: |%msg-args }
}
$match.make: $msg;
}
sub msg-privmsg (%args, %msg-args) {
%args<params>[0] ~~ /^<[#&]>/
and return IRC::Client::Message::Privmsg::Channel.new:
:channel( %args<params>[0] ),
:text( %args<params>[1] ),
|%msg-args;
return IRC::Client::Message::Privmsg::Me.new:
:text( %args<params>[1] ),
|%msg-args;
}
sub msg-notice (%args, %msg-args) {
%args<params>[0] ~~ /^<[#&]>/
and return IRC::Client::Message::Notice::Channel.new:
:channel( %args<params>[0] ),
:text( %args<params>[1] ),
|%msg-args;
return IRC::Client::Message::Notice::Me.new:
:text( %args<params>[1] ),
|%msg-args;
}
sub msg-mode (%args, %msg-args) {
if %args<params>[0] ~~ /^<[#&]>/ {
my @modes;
for %args<params>[1..*-1].join.comb: /\S/ {
state $sign;
/<[+-]>/ and $sign = $_ and next;
@modes.push: $sign => $_;
};
return IRC::Client::Message::Mode::Channel.new:
:channel( %args<params>[0] ),
:modes( @modes ),
|%msg-args;
}
else {
return IRC::Client::Message::Mode::Me.new:
:modes( %args<params>[1..*-1].join.comb: /<[a..zA..Z]>/ ),
|%msg-args;
}
}
|