| 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; |