line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# $Id: Autoop.pm,v 1.11 2000-07-27 12:01:04-04 roderick Exp $ |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# Copyright (c) 1997-2000 Roderick Schertler. All rights reserved. |
4
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify |
5
|
|
|
|
|
|
|
# it under the same terms as Perl itself. |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
# XXX |
8
|
|
|
|
|
|
|
# - track nick changes |
9
|
|
|
|
|
|
|
|
10
|
1
|
|
|
1
|
|
776
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
43
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
package Sirc::Autoop; |
13
|
|
|
|
|
|
|
|
14
|
1
|
|
|
1
|
|
4
|
use Exporter (); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
24
|
|
15
|
1
|
|
|
1
|
|
675
|
use Sirc::Chantrack qw(%Chan_op %Chan_user %Chan_voice); |
|
1
|
|
|
|
|
4
|
|
|
1
|
|
|
|
|
155
|
|
16
|
1
|
|
|
1
|
|
6
|
use Sirc::LckHash (); |
|
1
|
|
|
|
|
9
|
|
|
1
|
|
|
|
|
36
|
|
17
|
1
|
|
|
|
|
134
|
use Sirc::Util qw(addcmd addhelp add_hook addhook ban_pattern |
18
|
|
|
|
|
|
|
docommand doset have_ops have_ops_q ieq |
19
|
|
|
|
|
|
|
mask_to_re notice optional_channel |
20
|
|
|
|
|
|
|
settable_boolean settable_int tell_question |
21
|
1
|
|
|
1
|
|
18
|
timer userhost xgetarg xtell); |
|
1
|
|
|
|
|
1
|
|
22
|
|
|
|
|
|
|
|
23
|
1
|
|
|
1
|
|
5
|
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK @Autoop %Autovoice); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
2897
|
|
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
$VERSION = do{my@r=q$Revision: 1.11 $=~/\d+/g;sprintf '%d.'.'%03d'x$#r,@r}; |
26
|
|
|
|
|
|
|
$VERSION .= '-l' if q$Locker: $ =~ /: \S/; |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
29
|
|
|
|
|
|
|
@EXPORT = qw(); |
30
|
|
|
|
|
|
|
@EXPORT_OK = qw(@Autoop %Autovoice); |
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# These variables are tied to /set options. The *_delay options can be |
33
|
|
|
|
|
|
|
# either an integer or a code ref which will compute it. You have to |
34
|
|
|
|
|
|
|
# use doset rather than /set to set them to a code ref. |
35
|
|
|
|
|
|
|
my $Autoop = 1; # no autoops done if false |
36
|
|
|
|
|
|
|
my $Autoop_delay = sub { 3 + 2 * int rand 4 }; # secs before trying to autoop |
37
|
|
|
|
|
|
|
my $Autovoice = 1; |
38
|
|
|
|
|
|
|
my $Autovoice_control = 1; # ops can control autovoice delay |
39
|
|
|
|
|
|
|
my $Autovoice_delay = sub { 3 + 2 * int rand 4 }; # secs before autovoice |
40
|
|
|
|
|
|
|
my $Autovoice_timeout = 60 * 60; # secs -v is sticky |
41
|
|
|
|
|
|
|
my $Debug = 0; |
42
|
|
|
|
|
|
|
my $Verbose = 0; |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
settable_boolean 'autoop', \$Autoop; |
45
|
|
|
|
|
|
|
settable_int 'autoop_delay', \$Autoop_delay, sub { $_[1] >= 0 }; |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
settable_boolean 'autovoice', \$Autovoice; |
48
|
|
|
|
|
|
|
settable_boolean 'autovoice_control', \$Autovoice_control; |
49
|
|
|
|
|
|
|
settable_int 'autovoice_delay', \$Autovoice_delay, sub { $_[1] >= 0 }; |
50
|
|
|
|
|
|
|
settable_int 'autovoice_timeout', \$Autovoice_timeout, sub { $_[1] >= 0 }; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
settable_boolean 'autoop_debug', \$Debug; |
53
|
|
|
|
|
|
|
settable_boolean 'autoop_verbose', \$Verbose; |
54
|
|
|
|
|
|
|
|
55
|
|
|
|
|
|
|
# @Autoop is a list of array references. The first element of each |
56
|
|
|
|
|
|
|
# array is a pattern to match against the channel, the second is a |
57
|
|
|
|
|
|
|
# pattern to match against the nick!user@host. The optional third is |
58
|
|
|
|
|
|
|
# either 'o' or 'v' (defaulting to 'o') to tell which mode to give. |
59
|
|
|
|
|
|
|
# |
60
|
|
|
|
|
|
|
# There's no user-level interface for adding data to this (yet). |
61
|
|
|
|
|
|
|
@Autoop = (); |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# This is a hash whose keys are are channel names. New keys should |
64
|
|
|
|
|
|
|
# get undef as value. Everybody joining one of the listed channels |
65
|
|
|
|
|
|
|
# will get a +v after $Autovoice_delay seconds. If somebody gets a -v |
66
|
|
|
|
|
|
|
# then leaves and rejoins, though, they won't get another +v unless |
67
|
|
|
|
|
|
|
# $Autovoice_timeout seconds have passed or somebody else gives them a |
68
|
|
|
|
|
|
|
# +v. |
69
|
|
|
|
|
|
|
# |
70
|
|
|
|
|
|
|
# There's no user-level interface for adding data to this (yet). |
71
|
|
|
|
|
|
|
# |
72
|
|
|
|
|
|
|
# The implementation causes each value to be a hashref pointing to |
73
|
|
|
|
|
|
|
# another hash. The keys of the second level hashes are ban_pattern |
74
|
|
|
|
|
|
|
# patterns converted to REs indicating the people who are in sticky -v |
75
|
|
|
|
|
|
|
# mode, the value for each is the time at which it got -v. The second |
76
|
|
|
|
|
|
|
# level hash will only be present if it has keys, as the last key is |
77
|
|
|
|
|
|
|
# removed the $Autovoice{$channel} entry is undeffed. |
78
|
|
|
|
|
|
|
tie %Autovoice, 'Sirc::LckHash'; |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub debug { |
81
|
0
|
0
|
|
0
|
0
|
|
xtell 'autoop debug ' . join '', @_ |
82
|
|
|
|
|
|
|
if $Debug; |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
sub verbose { |
86
|
0
|
0
|
0
|
0
|
0
|
|
xtell join '', @_ |
87
|
|
|
|
|
|
|
if $Verbose || $Debug; |
88
|
|
|
|
|
|
|
} |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
sub autoop_match { |
91
|
0
|
|
|
0
|
0
|
|
my ($channel, $nuh) = @_; |
92
|
|
|
|
|
|
|
|
93
|
0
|
|
|
|
|
|
debug "autoop_match @_"; |
94
|
0
|
|
|
|
|
|
for (@Autoop) { |
95
|
0
|
|
|
|
|
|
my ($channel_pat, $nuh_pat, $type) = @$_; |
96
|
|
|
|
|
|
|
|
97
|
0
|
0
|
|
|
|
|
$type = 'o' if !defined $type; |
98
|
0
|
0
|
0
|
|
|
|
if ($type ne 'o' && $type ne 'v') { |
99
|
0
|
|
|
|
|
|
tell_question "Invalid autoop type `$type'" |
100
|
|
|
|
|
|
|
. " for /$channel_pat/ /$nuh_pat/"; |
101
|
0
|
|
|
|
|
|
next; |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
|
104
|
0
|
|
|
|
|
|
my $one = $channel =~ /$channel_pat/i; |
105
|
0
|
|
|
|
|
|
my $two = $nuh =~ /$nuh_pat/i; |
106
|
0
|
|
|
|
|
|
debug "channel/user $one/$two on $channel_pat/$nuh_pat"; |
107
|
0
|
0
|
0
|
|
|
|
if ($one && $two) { |
108
|
0
|
|
|
|
|
|
return $type; |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
} |
111
|
0
|
|
|
|
|
|
return 0; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub sticky_devoice { |
115
|
0
|
|
|
0
|
0
|
|
my ($c, $n, $uh) = @_; |
116
|
0
|
|
|
|
|
|
my ($h, $s, $expire); |
117
|
|
|
|
|
|
|
|
118
|
0
|
|
|
|
|
|
$h = $Autovoice{$c}; |
119
|
0
|
0
|
|
|
|
|
return 0 unless $h; |
120
|
|
|
|
|
|
|
|
121
|
0
|
|
|
|
|
|
$expire = time - $Autovoice_timeout; |
122
|
0
|
|
|
|
|
|
$s = "$n!$uh"; |
123
|
0
|
|
|
|
|
|
for my $pat (keys %$h) { |
124
|
0
|
0
|
|
|
|
|
if ($h->{$pat} < $expire) { |
125
|
0
|
|
|
|
|
|
delete $h->{$pat}; |
126
|
|
|
|
|
|
|
# undef the %Autovoice value when the last member drops. |
127
|
0
|
0
|
|
|
|
|
if (!%$h) { |
128
|
0
|
|
|
|
|
|
undef $Autovoice{$c}; |
129
|
0
|
|
|
|
|
|
return 0; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
else { |
133
|
0
|
0
|
|
|
|
|
return 1 if $s =~ /$pat/; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
} |
136
|
0
|
|
|
|
|
|
return 0; |
137
|
|
|
|
|
|
|
} |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
sub autoop_do { |
140
|
0
|
|
|
0
|
0
|
|
my ($this_channel, $this_nick, $this_userhost, $type) = @_; |
141
|
0
|
|
|
|
|
|
my ($mode); |
142
|
|
|
|
|
|
|
|
143
|
0
|
|
|
|
|
|
debug "autoop_do @_"; |
144
|
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
|
$mode = $type; |
146
|
0
|
0
|
|
|
|
|
$mode = 'v' if $mode eq 'autovoice'; |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
# Don't +v or +o for ops. |
149
|
0
|
0
|
0
|
|
|
|
if ($Chan_op{$this_channel}{$this_nick}) { |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
150
|
0
|
|
|
|
|
|
debug "autoop_do skip $this_channel/$this_nick/$type opped"; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
# Don't +v people who got it already. |
154
|
|
|
|
|
|
|
elsif ($mode eq 'v' && $Chan_voice{$this_channel}{$this_nick}) { |
155
|
0
|
|
|
|
|
|
debug "autoop_do skip $this_channel/$this_nick/$type voiced"; |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
# Don't +v if we're not moderated. |
159
|
|
|
|
|
|
|
elsif ($mode eq 'v' && $::mode{lc $this_channel} !~ /m/) { |
160
|
0
|
|
|
|
|
|
debug "autoop_do skip $this_channel/$this_nick/$type not +m"; |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
# Don't autovoice people who have a sticky -v. |
164
|
|
|
|
|
|
|
elsif ($type eq 'autovoice' |
165
|
|
|
|
|
|
|
&& sticky_devoice $this_channel, $this_nick, $this_userhost) { |
166
|
0
|
|
|
|
|
|
debug "autoop_do skip $this_channel/$this_nick/$type sticky -v"; |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
# Don't bother if she left already |
170
|
|
|
|
|
|
|
elsif (!$Chan_user{$this_channel}{$this_nick}) { |
171
|
0
|
|
|
|
|
|
debug "autoop_do skip $this_channel/$this_nick/$type gone"; |
172
|
|
|
|
|
|
|
} |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
else { |
175
|
0
|
|
|
|
|
|
debug "autoop_do op $this_channel/$this_nick"; |
176
|
0
|
|
|
|
|
|
docommand "mode $this_channel +$mode $this_nick\n"; |
177
|
|
|
|
|
|
|
} |
178
|
|
|
|
|
|
|
}; |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
sub autoop_try { |
181
|
0
|
|
|
0
|
0
|
|
my ($this_channel, $this_nick, $this_userhost, $immediate) = @_; |
182
|
0
|
|
|
|
|
|
my (@base_arg); |
183
|
|
|
|
|
|
|
|
184
|
0
|
|
|
|
|
|
debug "autoop_try @_"; |
185
|
0
|
0
|
|
|
|
|
have_ops $this_channel or return; |
186
|
0
|
0
|
|
|
|
|
return if ieq $this_nick, $::nick; |
187
|
0
|
|
|
|
|
|
@base_arg = ($this_channel, $this_nick, $this_userhost); |
188
|
|
|
|
|
|
|
|
189
|
0
|
0
|
0
|
|
|
|
if ($Autoop && (my $type = autoop_match $this_channel, |
190
|
|
|
|
|
|
|
"$this_nick!$this_userhost")) { |
191
|
0
|
0
|
|
|
|
|
my $delay = $immediate |
|
|
0
|
|
|
|
|
|
192
|
|
|
|
|
|
|
? 0 |
193
|
|
|
|
|
|
|
: ref($Autoop_delay) eq 'CODE' |
194
|
|
|
|
|
|
|
? &$Autoop_delay(@base_arg) |
195
|
|
|
|
|
|
|
: $Autoop_delay; |
196
|
0
|
0
|
0
|
|
|
|
verbose "Queueing +$type for $this_nick on $this_channel in $delay" |
197
|
|
|
|
|
|
|
if $delay > 0 || $Debug; |
198
|
0
|
|
|
0
|
|
|
timer $delay, sub { autoop_do @base_arg, $type }; |
|
0
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
|
201
|
0
|
0
|
0
|
|
|
|
if ($Autovoice && exists $Autovoice{$this_channel}) { |
202
|
0
|
0
|
|
|
|
|
my $delay = $immediate |
|
|
0
|
|
|
|
|
|
203
|
|
|
|
|
|
|
? 0 |
204
|
|
|
|
|
|
|
: ref($Autovoice_delay) eq 'CODE' |
205
|
|
|
|
|
|
|
? &$Autovoice_delay(@base_arg) |
206
|
|
|
|
|
|
|
: $Autovoice_delay; |
207
|
0
|
0
|
0
|
|
|
|
verbose "Queueing autovoice for $this_nick on $this_channel in $delay" |
208
|
|
|
|
|
|
|
if $delay > 0 || $Debug; |
209
|
0
|
|
|
0
|
|
|
timer $delay, sub { autoop_do @base_arg, 'autovoice' }; |
|
0
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
} |
211
|
|
|
|
|
|
|
} |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
sub main::hook_autoop_join { |
214
|
0
|
|
|
0
|
|
|
my $channel = shift; |
215
|
0
|
|
|
|
|
|
my @arg = ($channel, $::who, "$::user\@$::host"); |
216
|
0
|
0
|
|
|
|
|
autoop_try @arg, 0 |
217
|
|
|
|
|
|
|
if have_ops_q $channel; |
218
|
|
|
|
|
|
|
} |
219
|
|
|
|
|
|
|
addhook 'join', 'autoop_join'; |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
# When a /names list comes by, note people who don't have a voice in |
222
|
|
|
|
|
|
|
# %Autovoice. Without this I'd try to +v them when I get +o myself. |
223
|
|
|
|
|
|
|
# This only has any effect when joining the channel, though it runs for |
224
|
|
|
|
|
|
|
# every /names. |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
sub main::hook_autoop_names { |
227
|
0
|
|
|
0
|
|
|
my ($rest) = @_; |
228
|
0
|
|
|
|
|
|
my ($x1, $x2, $channel, $list) = split ' ', $rest, 4; |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
# I used to test if the channel was +m here as well, but the on-join |
231
|
|
|
|
|
|
|
# channel mode change can come after the /names. |
232
|
0
|
0
|
|
|
|
|
return unless exists $Autovoice{$channel}; |
233
|
|
|
|
|
|
|
|
234
|
0
|
|
|
|
|
|
my $now = time; |
235
|
0
|
|
|
|
|
|
$list =~ s/^://; |
236
|
0
|
|
|
|
|
|
for my $who (split ' ', $list) { |
237
|
0
|
0
|
|
|
|
|
next if $who =~ /^[+@]/; |
238
|
|
|
|
|
|
|
userhost $who, sub { |
239
|
0
|
|
|
0
|
|
|
my $pat = mask_to_re ban_pattern $::who, $::user, $::host; |
240
|
0
|
|
0
|
|
|
|
$Autovoice{$channel}{$pat} ||= $now; |
241
|
0
|
|
|
|
|
|
}; |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
} |
244
|
|
|
|
|
|
|
addhook '353', 'autoop_names'; |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# /autoop [channel] |
247
|
|
|
|
|
|
|
sub main::cmd_autoop { |
248
|
0
|
|
|
0
|
|
|
debug "cmd_autoop $::args"; |
249
|
0
|
0
|
|
|
|
|
optional_channel or return; |
250
|
0
|
|
|
|
|
|
my $c = lc xgetarg; |
251
|
0
|
0
|
|
|
|
|
have_ops $c or return; |
252
|
0
|
0
|
|
|
|
|
$Autoop or return; |
253
|
0
|
|
|
|
|
|
userhost [keys %{ $Chan_user{$c} }], sub { |
254
|
0
|
|
|
0
|
|
|
autoop_try $c, $::who, "$::user\@$::host", 1; |
255
|
0
|
|
|
|
|
|
}; |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
addcmd 'autoop'; |
258
|
|
|
|
|
|
|
addhelp 'autoop', '[channel]', |
259
|
|
|
|
|
|
|
q{Uses your autoop list to op and voice people on the current channel. |
260
|
|
|
|
|
|
|
Since this happens automatically you don't normally have to do this, this |
261
|
|
|
|
|
|
|
command is useful if you'd had autoopping disabled, or if there's a bug |
262
|
|
|
|
|
|
|
in the system. |
263
|
|
|
|
|
|
|
}; |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
# Try an /autoop after receiving ops. |
266
|
|
|
|
|
|
|
add_hook '+op', sub { |
267
|
|
|
|
|
|
|
my ($c, $n) = @_; |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
timer 10, sub { main::cmd_autoop $c } if ieq $n, $::nick; |
270
|
|
|
|
|
|
|
}; |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
add_hook '-voice', sub { |
273
|
|
|
|
|
|
|
my ($c, $n) = @_; |
274
|
|
|
|
|
|
|
my ($now); |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
return unless $Autovoice; |
277
|
|
|
|
|
|
|
return unless exists $Autovoice{$c}; |
278
|
|
|
|
|
|
|
$now = time; |
279
|
|
|
|
|
|
|
userhost $n, sub { |
280
|
|
|
|
|
|
|
$Autovoice{$c}{mask_to_re ban_pattern $::who, $::user, $::host} |
281
|
|
|
|
|
|
|
= $now; |
282
|
|
|
|
|
|
|
}; |
283
|
|
|
|
|
|
|
}; |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
add_hook '+voice', sub { |
286
|
|
|
|
|
|
|
my ($c, $n) = @_; |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
return unless $Autovoice{$c}; |
289
|
|
|
|
|
|
|
userhost $n, sub { |
290
|
|
|
|
|
|
|
delete $Autovoice{$c}{mask_to_re |
291
|
|
|
|
|
|
|
ban_pattern $::who, $::user, $::host}; |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
# If that was the last pattern, drop the hash ref. |
294
|
|
|
|
|
|
|
undef $Autovoice{$c} unless %{ $Autovoice{$c} }; |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
}; |
297
|
|
|
|
|
|
|
|
298
|
|
|
|
|
|
|
# Allow ops on autovoiced channels to control your autovoice delay with |
299
|
|
|
|
|
|
|
# a specially formatted /msg. |
300
|
|
|
|
|
|
|
# |
301
|
|
|
|
|
|
|
# autovoice report current value |
302
|
|
|
|
|
|
|
# autovoice N set it to N |
303
|
|
|
|
|
|
|
# autovoice +N add N seconds to the delay |
304
|
|
|
|
|
|
|
# autovoice -N remove N seconds from the delay |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
sub main::hook_autovoice_control_msg { |
307
|
0
|
|
|
0
|
|
|
my ($msg) = @_; |
308
|
0
|
0
|
|
|
|
|
return unless $msg =~ s/^\s*autovoice\b//i; |
309
|
0
|
0
|
|
|
|
|
return unless $Autovoice_control; |
310
|
0
|
|
|
|
|
|
debug "autovoice_control_msg [$msg] who [$::who]"; |
311
|
|
|
|
|
|
|
|
312
|
0
|
0
|
|
|
|
|
if (!grep { $Chan_op{$_}{$::who} } keys %Autovoice) { |
|
0
|
|
|
|
|
|
|
313
|
0
|
|
|
|
|
|
notice $::who, "You aren't an op on a channel I'm autovoicing."; |
314
|
0
|
|
|
|
|
|
return; |
315
|
|
|
|
|
|
|
} |
316
|
|
|
|
|
|
|
|
317
|
0
|
0
|
|
|
|
|
if (ref $Autovoice_delay) { |
318
|
0
|
|
|
|
|
|
notice $::who, "My autovoice delay is a code ref, " |
319
|
|
|
|
|
|
|
. "so remote control isn't available."; |
320
|
0
|
|
|
|
|
|
return; |
321
|
|
|
|
|
|
|
} |
322
|
|
|
|
|
|
|
|
323
|
0
|
|
|
|
|
|
my $new; |
324
|
0
|
0
|
|
|
|
|
if ($msg =~ /^\s*$/) { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
325
|
0
|
|
|
|
|
|
notice $::who, "Current autovoice delay is $Autovoice_delay."; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
elsif ($msg =~ /^\s*(\d+)\s*$/) { |
328
|
0
|
|
|
|
|
|
$new = $1; |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
elsif ($msg =~ /^\s*([+-]\s*\d+)\s*$/) { |
331
|
0
|
|
|
|
|
|
my $n = $1; |
332
|
0
|
|
|
|
|
|
$n =~ s/\s+//g; |
333
|
0
|
|
|
|
|
|
$new = $Autovoice_delay + $n; |
334
|
|
|
|
|
|
|
} |
335
|
|
|
|
|
|
|
else { |
336
|
0
|
|
|
|
|
|
notice $::who, "Unrecognized autovoice command, use: `autovoice', " |
337
|
|
|
|
|
|
|
. "`autovoice N', `autovoice +N', `autovoice -N'."; |
338
|
|
|
|
|
|
|
} |
339
|
|
|
|
|
|
|
|
340
|
0
|
0
|
|
|
|
|
if (defined $new) { |
341
|
0
|
0
|
|
|
|
|
if ($new < 0) { |
|
|
0
|
|
|
|
|
|
342
|
0
|
|
|
|
|
|
notice $::who, "Ignoring invalid delay $new."; |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
elsif ($new < 1) { |
345
|
0
|
|
|
|
|
|
notice $::who, "Ignoring too-low delay $new, " |
346
|
|
|
|
|
|
|
. "it would cause +v floods on netjoins."; |
347
|
|
|
|
|
|
|
} |
348
|
|
|
|
|
|
|
else { |
349
|
0
|
|
|
|
|
|
doset 'autovoice_delay', $new; |
350
|
0
|
|
|
|
|
|
notice $::who, "Autovoice delay set to $Autovoice_delay."; |
351
|
|
|
|
|
|
|
} |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
} |
354
|
|
|
|
|
|
|
addhook 'msg', 'autovoice_control_msg'; |
355
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
1; |