| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package POE::Component::IRC::Plugin::MultiProxy::State; |
|
2
|
|
|
|
|
|
|
BEGIN { |
|
3
|
1
|
|
|
1
|
|
1546
|
$POE::Component::IRC::Plugin::MultiProxy::State::AUTHORITY = 'cpan:HINRIK'; |
|
4
|
|
|
|
|
|
|
} |
|
5
|
|
|
|
|
|
|
BEGIN { |
|
6
|
1
|
|
|
1
|
|
16
|
$POE::Component::IRC::Plugin::MultiProxy::State::VERSION = '0.01'; |
|
7
|
|
|
|
|
|
|
} |
|
8
|
|
|
|
|
|
|
|
|
9
|
1
|
|
|
1
|
|
9
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
52
|
|
|
10
|
1
|
|
|
1
|
|
5
|
use warnings FATAL => 'all'; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
39
|
|
|
11
|
1
|
|
|
1
|
|
5
|
use POE::Filter::IRCD; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
29
|
|
|
12
|
1
|
|
|
1
|
|
9
|
use POE::Component::IRC::Common qw(parse_user u_irc); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
64
|
|
|
13
|
1
|
|
|
1
|
|
5
|
use POE::Component::IRC::Plugin qw(:ALL); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
3985
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
sub new { |
|
16
|
0
|
|
|
0
|
1
|
|
my ($package) = @_; |
|
17
|
0
|
|
|
|
|
|
return bless { }, $package; |
|
18
|
|
|
|
|
|
|
} |
|
19
|
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
sub PCI_register { |
|
21
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = @_; |
|
22
|
0
|
|
|
|
|
|
$self->{irc} = $irc; |
|
23
|
0
|
|
|
|
|
|
$self->{filter} = POE::Filter::IRCD->new(); |
|
24
|
0
|
|
|
|
|
|
$irc->plugin_register($self, SERVER => qw(001 away_sync_start away_sync_end join chan_mode chan_sync chan_sync_invex chan_sync_excepts nick_sync raw)); |
|
25
|
0
|
|
|
|
|
|
return 1; |
|
26
|
|
|
|
|
|
|
} |
|
27
|
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub PCI_unregister { |
|
29
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = @_; |
|
30
|
0
|
|
|
|
|
|
return 1; |
|
31
|
|
|
|
|
|
|
} |
|
32
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub S_001 { |
|
34
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = splice @_, 0, 2; |
|
35
|
0
|
|
|
|
|
|
$self->{syncing_away} = { }; |
|
36
|
0
|
|
|
|
|
|
$self->{syncing_op} = { }; |
|
37
|
0
|
|
|
|
|
|
$self->{syncing_join} = { }; |
|
38
|
0
|
|
|
|
|
|
$self->{op_queue} = { }; |
|
39
|
0
|
|
|
|
|
|
$self->{join_queue} = { }; |
|
40
|
|
|
|
|
|
|
|
|
41
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
|
42
|
|
|
|
|
|
|
} |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub S_join { |
|
45
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = splice @_, 0, 2; |
|
46
|
0
|
|
|
|
|
|
my $mapping = $irc->isupport('CASEMAPPING'); |
|
47
|
0
|
|
|
|
|
|
my $unick = u_irc((parse_user(${ $_[0] }))[0], $mapping); |
|
|
0
|
|
|
|
|
|
|
|
48
|
0
|
|
|
|
|
|
my $uchan = u_irc(${ $_[1] }, $mapping); |
|
|
0
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
|
|
50
|
0
|
0
|
|
|
|
|
if ($unick eq u_irc($irc->nick_name(), $mapping)) { |
|
51
|
0
|
|
|
|
|
|
$self->{syncing_join}{$uchan} = 1; |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
else { |
|
54
|
0
|
|
|
|
|
|
$self->{syncing_join}{$unick}++; |
|
55
|
|
|
|
|
|
|
} |
|
56
|
|
|
|
|
|
|
|
|
57
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
sub S_away_sync_start { |
|
61
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = splice @_, 0, 2; |
|
62
|
0
|
|
|
|
|
|
my $mapping = $irc->isupport('CASEMAPPING'); |
|
63
|
0
|
|
|
|
|
|
my $uchan = u_irc(${ $_[0] }, $mapping); |
|
|
0
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
|
|
65
|
0
|
|
|
|
|
|
$self->{syncing_away}{$uchan} = 1; |
|
66
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
|
67
|
|
|
|
|
|
|
} |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
sub S_away_sync_end { |
|
70
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = splice @_, 0, 2; |
|
71
|
0
|
|
|
|
|
|
my $mapping = $irc->isupport('CASEMAPPING'); |
|
72
|
0
|
|
|
|
|
|
my $uchan = u_irc(${ $_[0] }, $mapping); |
|
|
0
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
|
|
74
|
0
|
|
|
|
|
|
delete $self->{syncing_away}{$uchan}; |
|
75
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
|
76
|
|
|
|
|
|
|
} |
|
77
|
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
sub S_chan_mode { |
|
79
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = splice @_, 0, 2; |
|
80
|
0
|
|
|
|
|
|
my $mapping = $irc->isupport('CASEMAPPING'); |
|
81
|
0
|
|
|
|
|
|
my $uchan = u_irc(${ $_[1] }, $mapping); |
|
|
0
|
|
|
|
|
|
|
|
82
|
0
|
|
|
|
|
|
my $mode = ${ $_[2] }; |
|
|
0
|
|
|
|
|
|
|
|
83
|
0
|
|
|
|
|
|
my $unick = u_irc($irc->nick_name(), $mapping); |
|
84
|
|
|
|
|
|
|
|
|
85
|
0
|
0
|
|
|
|
|
if ($mode =~ /\+o/) { |
|
86
|
0
|
|
|
|
|
|
my @operands = split / /, ${ $_[3] }; |
|
|
0
|
|
|
|
|
|
|
|
87
|
0
|
0
|
|
|
|
|
if (grep { u_irc($_, $mapping) eq $unick } @operands) { |
|
|
0
|
|
|
|
|
|
|
|
88
|
0
|
|
|
|
|
|
$self->{syncing_op}{$uchan}{invex} = 1; |
|
89
|
0
|
|
|
|
|
|
$self->{syncing_op}{$uchan}{excepts} = 1; |
|
90
|
|
|
|
|
|
|
} |
|
91
|
|
|
|
|
|
|
} |
|
92
|
|
|
|
|
|
|
|
|
93
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
|
94
|
|
|
|
|
|
|
} |
|
95
|
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
sub S_chan_sync { |
|
97
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = splice @_, 0, 2; |
|
98
|
0
|
|
|
|
|
|
my $mapping = $irc->isupport('CASEMAPPING'); |
|
99
|
0
|
|
|
|
|
|
my $uchan = u_irc(${ $_[0] }, $mapping); |
|
|
0
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
101
|
0
|
|
|
|
|
|
delete $self->{syncing_join}{$uchan}; |
|
102
|
0
|
|
|
|
|
|
$self->_flush_queue($self->{join_queue}{$uchan}); |
|
103
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
sub S_chan_sync_invex { |
|
107
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = splice @_, 0, 2; |
|
108
|
0
|
|
|
|
|
|
my $mapping = $irc->isupport('CASEMAPPING'); |
|
109
|
0
|
|
|
|
|
|
my $uchan = u_irc(${ $_[0] }, $mapping); |
|
|
0
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
|
|
111
|
0
|
|
|
|
|
|
$self->_flush_queue($self->{op_queue}{$uchan}{invex}); |
|
112
|
0
|
|
|
|
|
|
delete $self->{syncing_op}{$uchan}{invex}; |
|
113
|
0
|
0
|
|
|
|
|
delete $self->{syncing_op}{$uchan} if !keys %{ $self->{syncing_op}{$uchan} }; |
|
|
0
|
|
|
|
|
|
|
|
114
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
|
115
|
|
|
|
|
|
|
} |
|
116
|
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
sub S_chan_sync_excepts { |
|
118
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = splice @_, 0, 2; |
|
119
|
0
|
|
|
|
|
|
my $mapping = $irc->isupport('CASEMAPPING'); |
|
120
|
0
|
|
|
|
|
|
my $uchan = u_irc(${ $_[0] }, $mapping); |
|
|
0
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
|
|
122
|
0
|
|
|
|
|
|
$self->_flush_queue($self->{op_queue}{$uchan}{excepts}); |
|
123
|
0
|
|
|
|
|
|
delete $self->{syncing_op}{$uchan}{excepts}; |
|
124
|
0
|
0
|
|
|
|
|
delete $self->{syncing_op}{$uchan} if !keys %{ $self->{syncing_op}{$uchan} }; |
|
|
0
|
|
|
|
|
|
|
|
125
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
|
126
|
|
|
|
|
|
|
} |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub S_nick_sync { |
|
129
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = splice @_, 0, 2; |
|
130
|
0
|
|
|
|
|
|
my $mapping = $irc->isupport('CASEMAPPING'); |
|
131
|
0
|
|
|
|
|
|
my $unick = u_irc(${ $_[0] }, $mapping); |
|
|
0
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
|
|
133
|
0
|
|
|
|
|
|
$self->{syncing_join}{$unick}--; |
|
134
|
0
|
0
|
|
|
|
|
delete $self->{syncing_join}{$unick} if $self->{syncing_join}{$unick} == 0; |
|
135
|
0
|
|
|
|
|
|
$self->_flush_queue($self->{join_queue}{$unick}); |
|
136
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
|
137
|
|
|
|
|
|
|
} |
|
138
|
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub S_raw { |
|
140
|
0
|
|
|
0
|
0
|
|
my ($self, $irc) = splice @_, 0, 2; |
|
141
|
0
|
|
|
|
|
|
my $mapping = $irc->isupport('CASEMAPPING'); |
|
142
|
0
|
|
|
|
|
|
my $raw_line = ${ $_[0] }; |
|
|
0
|
|
|
|
|
|
|
|
143
|
0
|
|
|
|
|
|
my $input = $self->{filter}->get( [ $raw_line ] )->[0]; |
|
144
|
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
# syncing_join me |
|
146
|
0
|
0
|
|
|
|
|
if ($input->{command} =~ /315|324|329|352|367|368/) { |
|
147
|
0
|
0
|
|
|
|
|
if ($input->{params}[1] =~ /[^#&+!]/) { |
|
148
|
0
|
0
|
|
|
|
|
if ($self->{syncing_join}{u_irc($input->{params}[1], $mapping)}) { |
|
149
|
0
|
|
|
|
|
|
return PCI_EAT_PLUGIN; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
} |
|
152
|
|
|
|
|
|
|
} |
|
153
|
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# syncing_join other |
|
155
|
0
|
0
|
|
|
|
|
if ($input->{command} eq '352') { |
|
156
|
0
|
0
|
|
|
|
|
if ($self->{syncing_join}{u_irc($input->{params}[5], $mapping)}) { |
|
157
|
0
|
|
|
|
|
|
return PCI_EAT_PLUGIN; |
|
158
|
|
|
|
|
|
|
} |
|
159
|
|
|
|
|
|
|
} |
|
160
|
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# syncing_away |
|
162
|
0
|
0
|
|
|
|
|
if ($input->{command} =~ /315|352/) { |
|
163
|
0
|
0
|
|
|
|
|
if ($input->{params}[1] =~ /[^#&+!]/) { |
|
164
|
0
|
0
|
|
|
|
|
if ($self->{syncing_away}{u_irc($input->{params}[1], $mapping)}) { |
|
165
|
0
|
|
|
|
|
|
return PCI_EAT_PLUGIN; |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
} |
|
168
|
|
|
|
|
|
|
} |
|
169
|
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
# syncing_op invex |
|
171
|
0
|
0
|
|
|
|
|
if ($input->{command} =~ /346|347/) { |
|
172
|
0
|
0
|
|
|
|
|
if ($self->{syncing_op}{u_irc($input->{params}[1], $mapping)}{invex}) { |
|
173
|
0
|
|
|
|
|
|
return PCI_EAT_PLUGIN; |
|
174
|
|
|
|
|
|
|
} |
|
175
|
|
|
|
|
|
|
} |
|
176
|
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# syncing_op excepts |
|
178
|
0
|
0
|
|
|
|
|
if ($input->{command} =~ /348|349/) { |
|
179
|
0
|
0
|
|
|
|
|
if ($self->{syncing_op}{u_irc($input->{params}[1], $mapping)}{excepts}) { |
|
180
|
0
|
|
|
|
|
|
return PCI_EAT_PLUGIN; |
|
181
|
|
|
|
|
|
|
} |
|
182
|
|
|
|
|
|
|
} |
|
183
|
|
|
|
|
|
|
|
|
184
|
0
|
|
|
|
|
|
return PCI_EAT_NONE; |
|
185
|
|
|
|
|
|
|
} |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
sub _flush_queue { |
|
188
|
0
|
|
|
0
|
|
|
my ($self, $queue) = @_; |
|
189
|
0
|
0
|
|
|
|
|
return if !$queue; |
|
190
|
|
|
|
|
|
|
|
|
191
|
0
|
|
|
|
|
|
while (my $request = shift @$queue) { |
|
192
|
0
|
|
|
|
|
|
my ($callback, $reply, $real_what, $args) = @{ $request }; |
|
|
0
|
|
|
|
|
|
|
|
193
|
0
|
|
|
|
|
|
$callback->($_) for $self->$reply($real_what, @{ $args }); |
|
|
0
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
} |
|
195
|
|
|
|
|
|
|
|
|
196
|
0
|
|
|
|
|
|
return; |
|
197
|
|
|
|
|
|
|
} |
|
198
|
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
sub is_syncing { |
|
200
|
0
|
|
|
0
|
1
|
|
my ($self, $what) = @_; |
|
201
|
0
|
|
|
|
|
|
my $mapping = $self->{irc}->isupport('CASEMAPPING'); |
|
202
|
0
|
|
|
|
|
|
my $uwhat = u_irc($what, $mapping); |
|
203
|
|
|
|
|
|
|
|
|
204
|
0
|
0
|
|
|
|
|
return 1 if $self->{syncing_join}{$uwhat}; |
|
205
|
0
|
|
|
|
|
|
return; |
|
206
|
|
|
|
|
|
|
} |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
sub enqueue { |
|
209
|
0
|
|
|
0
|
1
|
|
my ($self, $callback, $reply, $what, @args) = @_; |
|
210
|
0
|
|
|
|
|
|
my $mapping = $self->{irc}->isupport('CASEMAPPING'); |
|
211
|
0
|
|
|
|
|
|
my $uwhat = u_irc($what, $mapping); |
|
212
|
|
|
|
|
|
|
|
|
213
|
0
|
0
|
|
|
|
|
if ($reply eq 'mode_reply') { |
|
|
|
0
|
|
|
|
|
|
|
214
|
0
|
0
|
0
|
|
|
|
if (grep { defined && $_ eq 'e' } @args && $self->{syncing_op}{$uwhat}{excepts}) { |
|
|
0
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
215
|
0
|
|
|
|
|
|
push @{ $self->{op_queue}{$uwhat}{excepts} }, [$callback, $reply, $what, \@args]; |
|
|
0
|
|
|
|
|
|
|
|
216
|
0
|
|
|
|
|
|
return; |
|
217
|
|
|
|
|
|
|
} |
|
218
|
|
|
|
|
|
|
elsif (grep { defined && $_ eq 'I' } @args && $self->{syncing_op}{$uwhat}{invex}) { |
|
219
|
0
|
|
|
|
|
|
push @{ $self->{op_queue}{$uwhat}{invex} }, [$callback, $reply, $what, \@args]; |
|
|
0
|
|
|
|
|
|
|
|
220
|
0
|
|
|
|
|
|
return; |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
elsif ($self->{syncing_join}{$uwhat}) { |
|
223
|
0
|
|
|
|
|
|
push @{ $self->{join_queue}{$uwhat} }, [$callback, $reply, $what, \@args]; |
|
|
0
|
|
|
|
|
|
|
|
224
|
0
|
|
|
|
|
|
return; |
|
225
|
|
|
|
|
|
|
} |
|
226
|
|
|
|
|
|
|
} |
|
227
|
|
|
|
|
|
|
elsif ($reply =~ /(?:who|names|topic)_reply/) { |
|
228
|
0
|
0
|
|
|
|
|
if ($self->{syncing_join}{$uwhat}) { |
|
229
|
0
|
|
|
|
|
|
push @{ $self->{join_queue}{$uwhat} }, [$callback, $reply, $what, \@args]; |
|
|
0
|
|
|
|
|
|
|
|
230
|
0
|
|
|
|
|
|
return; |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
} |
|
233
|
|
|
|
|
|
|
|
|
234
|
0
|
|
|
|
|
|
my @lines = $self->$reply($what, @args); |
|
235
|
0
|
|
|
|
|
|
$callback->(@lines); |
|
236
|
0
|
|
|
|
|
|
return; |
|
237
|
|
|
|
|
|
|
} |
|
238
|
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
# handles /^TOPIC (\S+)$/ where $1 is a channel that we're on |
|
240
|
|
|
|
|
|
|
sub topic_reply { |
|
241
|
0
|
|
|
0
|
1
|
|
my ($self, $chan) = @_; |
|
242
|
0
|
|
|
|
|
|
my $irc = $self->{irc}; |
|
243
|
0
|
|
|
|
|
|
my $me = $irc->nick_name(); |
|
244
|
0
|
|
|
|
|
|
my $server = $irc->server_name(); |
|
245
|
0
|
|
|
|
|
|
my @results; |
|
246
|
|
|
|
|
|
|
|
|
247
|
0
|
0
|
|
|
|
|
if (!keys %{ $irc->channel_topic($chan) }) { |
|
|
0
|
|
|
|
|
|
|
|
248
|
0
|
|
|
|
|
|
push @results, ":$server 331 $me $chan :No topic is set"; |
|
249
|
|
|
|
|
|
|
} |
|
250
|
|
|
|
|
|
|
else { |
|
251
|
0
|
|
|
|
|
|
my $topic_info = $irc->channel_topic($chan); |
|
252
|
0
|
|
|
|
|
|
push @results, ":$server 332 $me $chan :" . $topic_info->{Value}; |
|
253
|
0
|
|
|
|
|
|
push @results, ":$server 333 $me $chan " . join(' ', @{$topic_info}{qw(SetBy SetAt)}); |
|
|
0
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
} |
|
255
|
|
|
|
|
|
|
|
|
256
|
0
|
|
|
|
|
|
return @results; |
|
257
|
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
} |
|
259
|
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
# handles /^NAMES (\S+)$/ where $1 is a channel that we're on |
|
261
|
|
|
|
|
|
|
sub names_reply { |
|
262
|
0
|
|
|
0
|
1
|
|
my ($self, $chan) = @_; |
|
263
|
0
|
|
|
|
|
|
my $irc = $self->{irc}; |
|
264
|
0
|
|
|
|
|
|
my $me = $irc->nick_name(); |
|
265
|
0
|
|
|
|
|
|
my $server = $irc->server_name(); |
|
266
|
0
|
|
|
|
|
|
my $chan_type = '='; |
|
267
|
0
|
0
|
|
|
|
|
$chan_type = '@' if $irc->is_channel_mode_set($chan, 's'); |
|
268
|
0
|
0
|
|
|
|
|
$chan_type = '*' if $irc->is_channel_mode_set($chan, 'p'); |
|
269
|
|
|
|
|
|
|
|
|
270
|
0
|
|
|
|
|
|
my @nicks = sort map { |
|
271
|
0
|
|
|
|
|
|
my $nick = $_; |
|
272
|
0
|
|
|
|
|
|
my $prefix = ''; |
|
273
|
0
|
0
|
|
|
|
|
$prefix = '+' if $irc->has_channel_voice($chan, $nick); |
|
274
|
0
|
0
|
|
|
|
|
$prefix = '%' if $irc->is_channel_halfop($chan, $nick); |
|
275
|
0
|
0
|
|
|
|
|
$prefix = '@' if $irc->is_channel_operator($chan, $nick); |
|
276
|
0
|
|
|
|
|
|
$prefix . $nick; |
|
277
|
|
|
|
|
|
|
} $irc->channel_list($chan); |
|
278
|
|
|
|
|
|
|
|
|
279
|
0
|
|
|
|
|
|
my $length = length($server) + length($chan) + length($me) + 11; |
|
280
|
0
|
|
|
|
|
|
my @results; |
|
281
|
0
|
|
|
|
|
|
my $nick_list = shift @nicks; |
|
282
|
|
|
|
|
|
|
|
|
283
|
0
|
|
|
|
|
|
for my $nick (@nicks) { |
|
284
|
0
|
0
|
|
|
|
|
if (length("$nick_list $nick") + $length <= 510) { |
|
285
|
0
|
|
|
|
|
|
$nick_list .= " $nick"; |
|
286
|
|
|
|
|
|
|
} |
|
287
|
|
|
|
|
|
|
else { |
|
288
|
0
|
|
|
|
|
|
push @results, ":$server 353 $me $chan_type $chan :$nick_list"; |
|
289
|
0
|
|
|
|
|
|
$nick_list = $nick; |
|
290
|
|
|
|
|
|
|
} |
|
291
|
|
|
|
|
|
|
} |
|
292
|
|
|
|
|
|
|
|
|
293
|
0
|
|
|
|
|
|
push @results, ":$server 353 $me $chan_type $chan :$nick_list"; |
|
294
|
0
|
|
|
|
|
|
push @results, ":$server 366 $me $chan :End of NAMES list"; |
|
295
|
|
|
|
|
|
|
|
|
296
|
0
|
|
|
|
|
|
return @results; |
|
297
|
|
|
|
|
|
|
} |
|
298
|
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
# handles /^WHO (\S+)$/ where $1 is a channel we're on or a nickname, NOT a mask |
|
300
|
|
|
|
|
|
|
sub who_reply { |
|
301
|
0
|
|
|
0
|
1
|
|
my ($self, $who) = @_; |
|
302
|
0
|
|
|
|
|
|
my $irc = $self->{irc}; |
|
303
|
0
|
|
|
|
|
|
my $me = $irc->nick_name(); |
|
304
|
0
|
|
|
|
|
|
my $server = $irc->server_name(); |
|
305
|
0
|
0
|
|
|
|
|
my $prefix = $who =~ /^[#&+!]/ ? $who : '*'; |
|
306
|
|
|
|
|
|
|
|
|
307
|
0
|
|
|
|
|
|
my @members; |
|
308
|
0
|
0
|
|
|
|
|
@members = $irc->channel_list($who) if $irc->is_channel_member($who, $me); |
|
309
|
0
|
0
|
|
|
|
|
@members = ($who) if $irc->_nick_exists($who); |
|
310
|
|
|
|
|
|
|
|
|
311
|
0
|
|
|
|
|
|
my @results; |
|
312
|
0
|
|
|
|
|
|
for my $member (@members) { |
|
313
|
0
|
|
|
|
|
|
my ($nick, $user, $host) = parse_user($irc->nick_long_form($member)); |
|
314
|
|
|
|
|
|
|
|
|
315
|
0
|
0
|
|
|
|
|
my $status = $irc->is_away($nick) ? 'G' : 'H'; |
|
316
|
0
|
0
|
|
|
|
|
$status .= '*' if $irc->is_operator($nick); |
|
317
|
0
|
0
|
|
|
|
|
$status .= '@' if $irc->is_channel_operator($who, $nick); |
|
318
|
0
|
0
|
|
|
|
|
$status .= '%' if $irc->is_channel_halfop($who, $nick); |
|
319
|
0
|
0
|
0
|
|
|
|
$status .= '+' if $irc->has_channel_voice($who, $nick) && !$irc->is_channel_operator($who, $nick); |
|
320
|
|
|
|
|
|
|
|
|
321
|
0
|
|
|
|
|
|
my $info = $irc->nick_info($nick); |
|
322
|
0
|
0
|
|
|
|
|
my $real = defined $info->{Real} ? $info->{Real} : ''; |
|
323
|
0
|
0
|
|
|
|
|
my $user_server = defined $info->{Server} ? $info->{Server} : '*'; |
|
324
|
0
|
0
|
|
|
|
|
my $hops = defined $info->{Hops} ? $info->{Hops} : '*'; |
|
325
|
0
|
|
|
|
|
|
push @results, ":$server 352 $me $prefix $user $host $user_server $nick $status :$hops $real"; |
|
326
|
|
|
|
|
|
|
} |
|
327
|
|
|
|
|
|
|
|
|
328
|
0
|
|
|
|
|
|
push @results, ":$server 315 $me $who :End of WHO list"; |
|
329
|
0
|
|
|
|
|
|
return @results; |
|
330
|
|
|
|
|
|
|
} |
|
331
|
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
# handles /^MODE #chan( [Ieb])?$/ and /^MODE our_nick$/ |
|
333
|
|
|
|
|
|
|
sub mode_reply { |
|
334
|
0
|
|
|
0
|
0
|
|
my ($self, $chan, $type) = @_; |
|
335
|
0
|
|
|
|
|
|
my $irc = $self->{irc}; |
|
336
|
0
|
|
|
|
|
|
my $mapping = $irc->isupport('CASEMAPPING'); |
|
337
|
0
|
|
|
|
|
|
my $me = $irc->nick_name(); |
|
338
|
0
|
|
|
|
|
|
my $server = $irc->server_name(); |
|
339
|
0
|
|
|
|
|
|
my @results; |
|
340
|
|
|
|
|
|
|
|
|
341
|
0
|
0
|
|
|
|
|
if (u_irc($chan, $mapping) eq u_irc($me, $mapping)) { |
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
342
|
0
|
|
|
|
|
|
return ":$server 221 $me :+" . $irc->umode(); |
|
343
|
|
|
|
|
|
|
} |
|
344
|
|
|
|
|
|
|
elsif (!defined $type) { |
|
345
|
0
|
|
|
|
|
|
my $modes = $irc->channel_modes($chan); |
|
346
|
|
|
|
|
|
|
|
|
347
|
0
|
|
|
|
|
|
my $mode_string = ''; |
|
348
|
0
|
|
|
|
|
|
while (my ($mode, $arg) = each %{ $modes }) { |
|
|
0
|
|
|
|
|
|
|
|
349
|
0
|
0
|
|
|
|
|
if (!length $arg) { |
|
350
|
0
|
|
|
|
|
|
$mode_string .= $mode; |
|
351
|
0
|
|
|
|
|
|
delete $modes->{$mode}; |
|
352
|
|
|
|
|
|
|
} |
|
353
|
|
|
|
|
|
|
} |
|
354
|
|
|
|
|
|
|
|
|
355
|
0
|
|
|
|
|
|
my @args; |
|
356
|
0
|
|
|
|
|
|
while (my ($mode, $arg) = each %{ $modes }) { |
|
|
0
|
|
|
|
|
|
|
|
357
|
0
|
|
|
|
|
|
$mode_string .= $mode; |
|
358
|
0
|
|
|
|
|
|
push @args, $arg; |
|
359
|
|
|
|
|
|
|
} |
|
360
|
|
|
|
|
|
|
|
|
361
|
0
|
0
|
|
|
|
|
$mode_string .= ' ' . join ' ', @args if @args; |
|
362
|
0
|
|
|
|
|
|
push @results, ":$server 324 $me $chan +$mode_string"; |
|
363
|
|
|
|
|
|
|
|
|
364
|
0
|
0
|
|
|
|
|
if ($irc->channel_creation_time($chan)) { |
|
365
|
0
|
|
|
|
|
|
my $time = $irc->channel_creation_time($chan); |
|
366
|
0
|
|
|
|
|
|
push @results, ":$server 329 $me $chan $time"; |
|
367
|
|
|
|
|
|
|
} |
|
368
|
|
|
|
|
|
|
} |
|
369
|
|
|
|
|
|
|
elsif ($type eq 'I') { |
|
370
|
0
|
|
|
|
|
|
while (my ($mask, $info) = each %{ $irc->channel_invex_list($chan) }) { |
|
|
0
|
|
|
|
|
|
|
|
371
|
0
|
|
|
|
|
|
push @results, ":$server 346 $me $chan $mask " . join (' ', @{$info}{qw(SetBy SetAt)}); |
|
|
0
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
} |
|
373
|
0
|
|
|
|
|
|
push @results, ":$server 347 $me $chan :End of Channel Invite List"; |
|
374
|
|
|
|
|
|
|
} |
|
375
|
|
|
|
|
|
|
elsif ($type eq 'e') { |
|
376
|
0
|
|
|
|
|
|
while (my ($mask, $info) = each %{ $irc->channel_except_list($chan) }) { |
|
|
0
|
|
|
|
|
|
|
|
377
|
0
|
|
|
|
|
|
push @results, ":$server 348 $me $chan $mask " . join (' ', @{$info}{qw(SetBy SetAt)}); |
|
|
0
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
} |
|
379
|
0
|
|
|
|
|
|
push @results, ":$server 349 $me $chan :End of Channel Exception List"; |
|
380
|
|
|
|
|
|
|
} |
|
381
|
|
|
|
|
|
|
elsif ($type eq 'b') { |
|
382
|
0
|
|
|
|
|
|
while (my ($mask, $info) = each %{ $irc->channel_ban_list($chan) }) { |
|
|
0
|
|
|
|
|
|
|
|
383
|
0
|
|
|
|
|
|
push @results, ":$server 367 $me $chan $mask " . join (' ', @{$info}{qw(SetBy SetAt)}); |
|
|
0
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
} |
|
385
|
0
|
|
|
|
|
|
push @results, ":$server 368 $me $chan :End of Channel Ban List"; |
|
386
|
|
|
|
|
|
|
} |
|
387
|
|
|
|
|
|
|
|
|
388
|
0
|
|
|
|
|
|
return @results; |
|
389
|
|
|
|
|
|
|
} |
|
390
|
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
1; |
|
392
|
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
=encoding utf8 |
|
394
|
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=head1 NAME |
|
396
|
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
POE::Compoent::IRC::Plugin::MultiProxy::State - Generates IRC server replies based on information provided by POE::Component::IRC::State |
|
398
|
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
400
|
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
use POE::Compoent::IRC::Plugin::MultiProxy::State; |
|
402
|
|
|
|
|
|
|
|
|
403
|
|
|
|
|
|
|
$irc->plugin_add('State', POE::Compoent::IRC::Plugin::MultiProxy::State->new()); |
|
404
|
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
=head1 DESCRIPTION |
|
406
|
|
|
|
|
|
|
|
|
407
|
|
|
|
|
|
|
POE::Compoent::IRC::Plugin::MultiProxy::::State is a |
|
408
|
|
|
|
|
|
|
L plugin. Its role is to use |
|
409
|
|
|
|
|
|
|
L's information as a |
|
410
|
|
|
|
|
|
|
cache so that fewer trips will be to the IRC server when clients submit |
|
411
|
|
|
|
|
|
|
queries. The methods here are only useful for a subset of the use cases that |
|
412
|
|
|
|
|
|
|
their corresponding commands are capable of, mostly because there are certain |
|
413
|
|
|
|
|
|
|
cases that only the actual IRC server can handle. However, the methods can |
|
414
|
|
|
|
|
|
|
handle all the automatic queries that modern IRC clients make, so it does the |
|
415
|
|
|
|
|
|
|
job. |
|
416
|
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
Another thing this plugin does is hide from clients all server replies |
|
418
|
|
|
|
|
|
|
elicited by L's |
|
419
|
|
|
|
|
|
|
information gathering. |
|
420
|
|
|
|
|
|
|
|
|
421
|
|
|
|
|
|
|
This plugin requires the IRC component to be |
|
422
|
|
|
|
|
|
|
L or a subclass thereof. |
|
423
|
|
|
|
|
|
|
|
|
424
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
|
425
|
|
|
|
|
|
|
|
|
426
|
|
|
|
|
|
|
=head2 C |
|
427
|
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
Takes no arguments. |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
Returns a plugin object suitable for feeding to |
|
431
|
|
|
|
|
|
|
L's C method. |
|
432
|
|
|
|
|
|
|
|
|
433
|
|
|
|
|
|
|
=head1 METHODS |
|
434
|
|
|
|
|
|
|
|
|
435
|
|
|
|
|
|
|
=head2 C |
|
436
|
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
One argument: |
|
438
|
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
An IRC channel which the IRC component is on |
|
440
|
|
|
|
|
|
|
|
|
441
|
|
|
|
|
|
|
Returns IRC protocol line responses to the C command. |
|
442
|
|
|
|
|
|
|
|
|
443
|
|
|
|
|
|
|
=head2 C |
|
444
|
|
|
|
|
|
|
|
|
445
|
|
|
|
|
|
|
One argument: |
|
446
|
|
|
|
|
|
|
|
|
447
|
|
|
|
|
|
|
An IRC channel which the IRC component is on |
|
448
|
|
|
|
|
|
|
|
|
449
|
|
|
|
|
|
|
Returns IRC protocol line responses to the C command. |
|
450
|
|
|
|
|
|
|
|
|
451
|
|
|
|
|
|
|
=head2 C |
|
452
|
|
|
|
|
|
|
|
|
453
|
|
|
|
|
|
|
One argument: |
|
454
|
|
|
|
|
|
|
|
|
455
|
|
|
|
|
|
|
An IRC channel which the IRC component is on, or a known nickname |
|
456
|
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
Returns IRC protocol line responses to the C command. |
|
458
|
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
=head2 C |
|
460
|
|
|
|
|
|
|
|
|
461
|
|
|
|
|
|
|
One or two arguments: |
|
462
|
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
The IRC component's nickname, or a channel which the component is on |
|
464
|
|
|
|
|
|
|
and an optional mode type |
|
465
|
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
Returns IRC protocol line responses to the C command. |
|
467
|
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
=head2 C |
|
469
|
|
|
|
|
|
|
|
|
470
|
|
|
|
|
|
|
In case a client asks for information about a channel while it is being |
|
471
|
|
|
|
|
|
|
synced, it should call this method, and the information will be provided |
|
472
|
|
|
|
|
|
|
as soon as it has been gathered. |
|
473
|
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
Takes three arguments: |
|
475
|
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
A code reference which will be called for every line of response generated, |
|
477
|
|
|
|
|
|
|
the type of reply being asked for (e.g. 'who_reply'), and the arguments |
|
478
|
|
|
|
|
|
|
to the corresponding method. |
|
479
|
|
|
|
|
|
|
|
|
480
|
|
|
|
|
|
|
=head2 C |
|
481
|
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
Takes one argument: |
|
483
|
|
|
|
|
|
|
|
|
484
|
|
|
|
|
|
|
An IRC channel. |
|
485
|
|
|
|
|
|
|
|
|
486
|
|
|
|
|
|
|
Returns 1 if the channel or nick is being synced, 0 otherwise. |
|
487
|
|
|
|
|
|
|
|
|
488
|
|
|
|
|
|
|
=head1 AUTHOR |
|
489
|
|
|
|
|
|
|
|
|
490
|
|
|
|
|
|
|
Hinrik Ern SigurEsson, hinrik.sig@gmail.com |
|
491
|
|
|
|
|
|
|
|
|
492
|
|
|
|
|
|
|
=cut |