/[cvs]/eggdrop1.6/scripts/sentinel.tcl
ViewVC logotype

Annotation of /eggdrop1.6/scripts/sentinel.tcl

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (hide annotations) (download) (as text)
Tue Apr 30 16:20:36 2002 UTC (17 years, 4 months ago) by wcc
Branch: MAIN
CVS Tags: r1, eggdrop_1_6_15, eggdrop_1_6_13, blah, test, v2_0, eggdrop1_6_11, HEAD
Changes since 1.3: +107 -73 lines
File MIME type: application/x-tcl
updated slennox's sentinel.tcl to the latest version

1 wcc 1.4 # sentinel.tcl v2.70 (15 April 2002)
2     # Copyright 1998-2002 by slennox
3 guppy 1.1 # slennox's eggdrop page - http://www.egghelp.org/
4 guppy 1.3
5 guppy 1.1 # Flood protection system for eggdrop, with integrated BitchX CTCP
6     # simulation. This script is designed to provide strong protection for your
7     # bot and channels against large floodnets and proxy floods.
8     #
9 guppy 1.2 # Note that this script was developed on the eggdrop 1.3, 1.4, and 1.6
10     # series and may not work properly on other versions.
11     #
12 guppy 1.1 # v2.00 - New standalone release. Contains refinements and features from
13     # the netbots.tcl version of sentinel.tcl.
14 guppy 1.2 # v2.50 - Locktimes of less than 30 were erroneously allowed.
15     # putquick -next is now supported (eggdrop 1.5+) for faster channel
16     # lock.
17 wcc 1.4 # - Ban mechanism now checks if flooders are coming from the same
18 guppy 1.2 # domain or ident and performs wildcard bans instead of banning
19     # each IP/host individually.
20 wcc 1.4 # - Added tsunami detection to the avalanche flood detection system.
21     # - Variables are now cleared after removing a channel.
22     # - Removed unnecessary botonchan checks throughout components where
23 guppy 1.2 # botisop already checks for that.
24 wcc 1.4 # - Removed all unnecessary use of parentheses.
25 guppy 1.3 # v2.60 - Modified putquick compatibility proc.
26 wcc 1.4 # - Added sl_wideban option to make domain/ident bans optional.
27     # - Fixed typos in various ban-related functions.
28     # - Unused procs are now unloaded.
29     # - Wildcard bans covering domains/idents were not doing proper
30 guppy 1.3 # checks on join-part flooders.
31 wcc 1.4 # v2.70 - Fixed "allbans" error which could occur when sl_wideban is
32     # disabled.
33     # - Added sl_masktype option, currently offering three different
34     # ban/ignore mask types.
35     # - Merged unsets in sl_unsetarray.
36     # - Changed use of "split" in timers to the less ugly "list".
37 guppy 1.1 #
38     # sentinel.tcl is centered around its channel lock mechanism. It sets the
39     # channel +mi (moderated and invite-only) whenever a substantial flood on
40     # the channel is detected. This ensures channel stability when flooded,
41     # allowing the bots to deal with the flood as smoothly as possible.
42     # sentinel.tcl detects the following types of floods:
43     #
44     # * Channel CTCP floods. This is the most common type of flood, and will
45     # often make users quit from the channel with 'Excess Flood'. A quick
46     # channel lock can prevent this.
47 guppy 1.2 # * Channel join-part floods. A common type of channel flood in which many
48     # floodbots cycle the channel.
49 guppy 1.1 # * Channel nick floods. Nick floods are unique in that they can occur even
50     # after a channel is locked. sentinel has special mechanisms to deal with
51     # this as effectively as possible.
52 guppy 1.2 # * Channel avalanche/tsunami floods. While the avalanche flood is quite
53     # uncommon these days, tsunami floods are often used to seriously lag
54     # mIRC and other clients using control codes (colour, bold, underline,
55     # etc.)
56 guppy 1.1 # * Channel text floods. Not small text floods - but when hundreds of
57     # messages are sent to the channel within a short period. Detected to
58 guppy 1.2 # stop really aggressive text floods and reduce the possibility of the
59     # bot crashing or consuming excessive CPU.
60 guppy 1.1 #
61     # sentinel also has additional protection features for the bot and channel:
62     #
63     # * Bogus username detection. Users with annoying bogus characters in their
64     # ident are banned. A channel lock is applied if multiple join in a short
65     # period.
66     # * Full ban list detection. During a serious flood, the ban list may
67     # become full. If this happens, the bots may start kick flooding since
68     # they cannot ban. If the ban list is full, the channel will be set +i.
69     # * Bot CTCP flood protection. Protects the bot if it is CTCP flooded.
70     # * Bot MSG flood protection. Protects the bot if it's flooded with MSGs or
71     # MSG commands.
72     # * Automatic bans and ignores. During a flood, sentinel will compile a
73 guppy 1.2 # list of the flooders, then kick-ban them after the channel has been
74 guppy 1.1 # locked.
75     # * BitchX simulation. This has been built-in mainly because you cannot use
76     # a third-party BitchX simulator with sentinel (only one script at a time
77     # can have control of CTCPs). sentinel provides accurate simulation of
78     # BitchX 75p1+ and 75p3+ CTCP replies and AWAY mode.
79     # * Public commands (lc and uc) and DCC commands (.lock and .unlock) for
80     # locking/unlocking channels.
81     # * DCC command .sentinel displays current settings.
82     #
83     # Important Notes:
84     # - Make sure no bots are enforcing channel mode -i and/or -m.
85     # - Bans are added to the bot's internal ban list, and expire after 24
86     # hours by default. If you have +dynamicbans set, the bans may be removed
87     # from the channel much sooner than this, but the ban will remain in the
88     # bot's internal ban list until it expires.
89     # - For greater protection against large channel floods, I recommend you
90 guppy 1.2 # also use a channel limiter script, such as chanlimit.tcl.
91 wcc 1.4 # - There is a trade-off between convenience and security. The more
92     # automation you enable, the more stress the bot will be under during a
93     # flood and the more stuff it will be sending to the server.
94 guppy 1.1 # - Where security is paramount, have one or two bots that aren't running
95     # sentinel.tcl. Since sentinel.tcl is a complex script with many
96 wcc 1.4 # automated and convenience features, there is a potential for
97 guppy 1.1 # vulnerabilities.
98    
99     # The following flood settings are in number:seconds format, 0:0 to
100     # disable.
101    
102     # Bot CTCP flood.
103     set sl_bcflood 5:30
104 guppy 1.2
105 guppy 1.1 # Bot MSG flood.
106     set sl_bmflood 6:20
107 guppy 1.2
108 guppy 1.1 # Channel CTCP flood.
109     set sl_ccflood 5:20
110 guppy 1.2
111     # Channel avalanche/tsunami flood.
112 guppy 1.1 set sl_avflood 6:20
113 guppy 1.2
114 guppy 1.1 # Channel text flood.
115     set sl_txflood 80:30
116 guppy 1.2
117 guppy 1.1 # Channel bogus username join flood.
118     set sl_boflood 4:20
119 guppy 1.2
120 guppy 1.1 # Channel join-part flood.
121     set sl_jflood 6:20
122 guppy 1.2
123 guppy 1.1 # Channel nick flood.
124     set sl_nkflood 6:20
125    
126     # Flood setting notes:
127     # - Don't fiddle too much with the seconds field in the flood settings, as
128     # it can reduce the effectiveness of the script. The seconds field should
129     # set in the 20-60 seconds range.
130 guppy 1.2 # - Avalanche/tsunmami flood detection may be CPU intensive on a busy
131     # channel, although I don't think it's a big deal on most systems. If
132     # you're concerned about CPU usage you may wish to disable it, perhaps
133     # leaving it enabled on one bot. Disabling text flood protection can
134     # further reduce CPU usage.
135     # - On bots with avalanche/tsunami flood detection enabled, it's
136     # recommended that you also enable text flood detection to cap CPU usage
137     # during a flood.
138 guppy 1.1 # - If you enable nick flood detection, it's strongly recommended that it
139     # be enabled on all bots that have sentinel.tcl loaded. This is required
140     # for effective nick flood handling.
141    
142 guppy 1.2 # Specify the number of control characters that must be in a line before
143     # it's counted by the tsunami flood detector. For efficiency reasons,
144     # tsunami detection is implemented with avalanche detection, so sl_avflood
145     # must be enabled for tsunami detection to be active. Setting this to 0
146     # will disable tsunami detection.
147     set sl_tsunami 10
148     # Valid settings: 0 to disable, otherwise 1 or higher.
149    
150 guppy 1.1 # Length of time in minutes to ban channel flooders. This makes the bot
151 guppy 1.3 # perform kicks and bans on flooders after the channel lock. Because of the
152     # reactive nature of automatic bans, you should disable this on at least
153     # one bot for the most effective protection.
154 guppy 1.1 set sl_ban 1440
155     # Valid settings: 0 to disable, otherwise 1 or higher.
156    
157     # Length of time in minutes of on-join bans for bogus usernames. For the
158     # most effective protection, you should disable this on at least one bot.
159     set sl_boban 1440
160     # Valid settings: 0 to disable, otherwise 1 or higher.
161    
162     # Set global bans on channel flooders and bogus usernames?
163     set sl_globalban 0
164     # Valid settings: 1 for global bans, 0 for channel-specific bans.
165    
166 guppy 1.3 # When processing a list of flooders, sentinel.tcl compares the hosts to
167     # see if multiple flooders are coming from a particular domain/IP or using
168     # the same ident (e.g. different vhosts on a single user account). If
169     # multiple flooders come from the same domain/IP, or if multiple flooders
170     # have the same ident, then the whole domain/IP (i.e. *!*@*.domain.com or
171     # *!*@555.555.555.*) or ident (i.e. *!*username@*) is banned. If you
172     # disable this option, all bans will be in *!*@machine.domain.com and
173     # *!*@555.555.555.555 format.
174     set sl_wideban 1
175     # Valid settings: 1 to enable, 0 to disable.
176    
177 guppy 1.1 # Maximum number of bans allowed in the bot's ban list before sentinel will
178     # stop adding new bans. This prevents the bot from adding hundreds of bans
179     # on really large floods. Note that this has nothing to do with the channel
180     # ban list.
181     set sl_banmax 100
182     # Valid settings: 1 or higher.
183    
184     # Length of time in minutes to ignore bot flooders. On bots with sl_ban
185     # active, channel flooders are also added to the ignore list.
186     set sl_igtime 240
187     # Valid settings: 1 or higher.
188    
189 wcc 1.4 # Select the type of hostmask to use when banning and/or ignoring flooders.
190     # There are three to choose from:
191     # 0 - *!*@machine.domain.com / *!*@555.555.555.555
192     # 1 - *!*ident@machine.domain.com / *!*ident@555.555.555.555
193     # 2 - *!*ident@*.domain.com / *!*ident@555.555.555.*
194     # The default option, 0, is strongly recommended for most situations, and
195     # provides the best level of protection. The other two options are provided
196     # mainly for special cases.
197     set sl_masktype 0
198     # Valid settings: 0, 1, or 2, depending on the hostmask type you wish to use.
199    
200 guppy 1.1 # Length of time in seconds to set channel +i if flooded. If set to 0, +i
201     # will not be removed automatically.
202     set sl_ilocktime 120
203     # Valid settings: 0 to prevent +i being removed automatically, otherwise 30
204     # or higher.
205    
206     # Length of time in seconds to set channel +m if flooded. If set to 0, +m
207     # will not be removed automatically.
208     set sl_mlocktime 60
209     # Valid settings: 0 to prevent +m being removed automatically, otherwise 30
210     # or higher.
211    
212     # On small floods (two flooders or less), remove the +mi shortly after bans
213     # have been set, instead of waiting for the locktimes to expire? This
214     # prevents unnecessary extended locks on small floods. This setting is only
215     # used by bots with sl_ban enabled.
216     set sl_shortlock 0
217     # Valid settings: 0 to disable, 1 to enable.
218    
219     # Number of bans to allow in the channel ban list before setting the
220     # channel +i. If enabled, this should preferably be set to just below the
221     # maximum number of bans allowed.
222     set sl_bfmaxbans 19
223     # Valid settings: 0 to disable +i on full ban list, otherwise 1 or higher.
224    
225     # List of users to send a note to when channel is flooded, bot is flooded,
226     # or ban list becomes full.
227     set sl_note "YourNick"
228     # Valid settings: one user like "Tom", a list of users like
229     # "Tom Dick Harry", or "" to specify that no notes are sent.
230    
231     # Notice to send to channel when locked due to flood.
232     set sl_cfnotice "Channel locked temporarily due to flood, sorry for any inconvenience this may cause :-)"
233     # Valid settings: a text string, or set it to "" to disable.
234    
235     # Notice to send to channel when locked due to full ban list.
236     set sl_bfnotice "Channel locked temporarily due to full ban list, sorry for any inconvenience this may cause :-)"
237 guppy 1.2 # Valid settings: a text string, or set it to "" to disable.
238 guppy 1.1
239     # Enable 'lc' and 'uc' public commands for locking/unlocking channel?
240     set sl_lockcmds 2
241     # Valid settings: 0 to disable, 1 to enable, 2 to require user to be opped
242     # on the channel to use the command.
243    
244     # Users with these flags are allowed to use lc/uc public commands, and
245     # .lock/.unlock DCC commands.
246     set sl_lockflags "o"
247     # Valid settings: one flag like "n", or a list of flags like "fo" (means
248     # 'f OR o').
249    
250     # Enable BitchX CTCP and AWAY simulation?
251     set sl_bxsimul 0
252     # Valid settings: 1 to enable, 0 to disable.
253    
254    
255     # Don't edit below unless you know what you're doing.
256    
257     if {$numversion < 1032400} {
258 guppy 1.2 proc botonchan {chan} {
259     global botnick
260     if {![validchan $chan]} {
261     error "illegal channel: $chan"
262     } elseif {![onchan $botnick $chan]} {
263     return 0
264 guppy 1.1 }
265 guppy 1.2 return 1
266 guppy 1.1 }
267 guppy 1.3 proc putquick {text args} {
268 guppy 1.1 putserv $text
269     }
270     }
271    
272     proc sl_ctcp {nick uhost hand dest key arg} {
273     global botnet-nick botnick realname sl_ban sl_bflooded sl_bcflood sl_bcqueue sl_bxjointime sl_bxmachine sl_bxonestack sl_bxsimul sl_bxsystem sl_bxversion sl_bxwhoami sl_ccbanhost sl_ccbannick sl_ccflood sl_ccqueue sl_flooded sl_locked sl_note
274     set chan [string tolower $dest]
275 guppy 1.2 if {[lsearch -exact $sl_ccflood 0] == -1 && [validchan $chan] && ![isop $nick $chan]} {
276 guppy 1.1 if {$nick == $botnick} {return 0}
277 guppy 1.2 if {$sl_ban && !$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
278     lappend sl_ccbannick($chan) $nick ; lappend sl_ccbanhost($chan) [string tolower $uhost]
279 wcc 1.4 utimer [lindex $sl_ccflood 1] [list sl_ccbanqueue $chan]
280 guppy 1.1 }
281     if {$sl_flooded($chan)} {return 1}
282     incr sl_ccqueue($chan)
283 wcc 1.4 utimer [lindex $sl_ccflood 1] [list sl_ccqueuereset $chan]
284 guppy 1.1 if {$sl_ccqueue($chan) >= [lindex $sl_ccflood 0]} {
285     sl_lock $chan "CTCP flood" ${botnet-nick} ; return 1
286     }
287     if {$sl_bflooded} {return 1}
288 guppy 1.2 } elseif {[lindex $sl_bcflood 0] && $dest == $botnick} {
289 guppy 1.1 if {$sl_bflooded} {
290 guppy 1.2 sl_ignore [string tolower $uhost] $hand "CTCP flooder" ; return 1
291 guppy 1.1 }
292     incr sl_bcqueue
293 wcc 1.4 utimer [lindex $sl_bcflood 1] {incr sl_bcqueue -1}
294 guppy 1.1 if {$sl_bcqueue >= [lindex $sl_bcflood 0]} {
295     putlog "sentinel: CTCP flood detected on me! Stopped answering CTCPs temporarily."
296     set sl_bflooded 1
297 wcc 1.4 utimer [lindex $sl_bcflood 1] {set sl_bflooded 0}
298 guppy 1.1 if {[info commands sendnote] != ""} {
299     foreach recipient $sl_note {
300     if {[validuser $recipient]} {
301     sendnote SENTINEL $recipient "Bot was CTCP flooded."
302     }
303     }
304     }
305     return 1
306     }
307     }
308    
309     if {!$sl_bxsimul} {return 0}
310     if {$sl_bxonestack} {return 1}
311 wcc 1.4 set sl_bxonestack 1 ; utimer 2 {set sl_bxonestack 0}
312 guppy 1.1 switch -exact -- $key {
313     "CLIENTINFO" {
314     set bxcmd [string toupper $arg]
315     switch -exact -- $bxcmd {
316     "" {putserv "NOTICE $nick :\001CLIENTINFO SED UTC ACTION DCC CDCC BDCC XDCC VERSION CLIENTINFO USERINFO ERRMSG FINGER TIME PING ECHO INVITE WHOAMI OP OPS UNBAN IDENT XLINK UPTIME :Use CLIENTINFO <COMMAND> to get more specific information\001"}
317     "SED" {putserv "NOTICE $nick :\001CLIENTINFO SED contains simple_encrypted_data\001"}
318     "UTC" {putserv "NOTICE $nick :\001CLIENTINFO UTC substitutes the local timezone\001"}
319     "ACTION" {putserv "NOTICE $nick :\001CLIENTINFO ACTION contains action descriptions for atmosphere\001"}
320     "DCC" {putserv "NOTICE $nick :\001CLIENTINFO DCC requests a direct_client_connection\001"}
321     "CDCC" {putserv "NOTICE $nick :\001CLIENTINFO CDCC checks cdcc info for you\001"}
322     "BDCC" {putserv "NOTICE $nick :\001CLIENTINFO BDCC checks cdcc info for you\001"}
323     "XDCC" {putserv "NOTICE $nick :\001CLIENTINFO XDCC checks cdcc info for you\001"}
324     "VERSION" {putserv "NOTICE $nick :\001CLIENTINFO VERSION shows client type, version and environment\001"}
325     "CLIENTINFO" {putserv "NOTICE $nick :\001CLIENTINFO CLIENTINFO gives information about available CTCP commands\001"}
326     "USERINFO" {putserv "NOTICE $nick :\001CLIENTINFO USERINFO returns user settable information\001"}
327     "ERRMSG" {putserv "NOTICE $nick :\001CLIENTINFO ERRMSG returns error messages\001"}
328     "FINGER" {putserv "NOTICE $nick :\001CLIENTINFO FINGER shows real name, login name and idle time of user\001"}
329     "TIME" {putserv "NOTICE $nick :\001CLIENTINFO TIME tells you the time on the user's host\001"}
330     "PING" {putserv "NOTICE $nick :\001CLIENTINFO PING returns the arguments it receives\001"}
331     "ECHO" {putserv "NOTICE $nick :\001CLIENTINFO ECHO returns the arguments it receives\001"}
332     "INVITE" {putserv "NOTICE $nick :\001CLIENTINFO INVITE invite to channel specified\001"}
333     "WHOAMI" {putserv "NOTICE $nick :\001CLIENTINFO WHOAMI user list information\001"}
334     "OP" {putserv "NOTICE $nick :\001CLIENTINFO OP ops the person if on userlist\001"}
335     "OPS" {putserv "NOTICE $nick :\001CLIENTINFO OPS ops the person if on userlist\001"}
336     "UNBAN" {putserv "NOTICE $nick :\001CLIENTINFO UNBAN unbans the person from channel\001"}
337     "IDENT" {putserv "NOTICE $nick :\001CLIENTINFO IDENT change userhost of userlist\001"}
338     "XLINK" {putserv "NOTICE $nick :\001CLIENTINFO XLINK x-filez rule\001"}
339     "UPTIME" {putserv "NOTICE $nick :\001CLIENTINFO UPTIME my uptime\001"}
340     "default" {putserv "NOTICE $nick :\001ERRMSG CLIENTINFO: $arg is not a valid function\001"}
341     }
342     return 1
343     }
344     "VERSION" {
345     putserv "NOTICE $nick :\001VERSION \002BitchX-$sl_bxversion\002 by panasync \002-\002 $sl_bxsystem :\002 Keep it to yourself!\002\001"
346     return 1
347     }
348     "USERINFO" {
349     putserv "NOTICE $nick :\001USERINFO \001"
350     return 1
351     }
352     "FINGER" {
353     putserv "NOTICE $nick :\001FINGER $realname ($sl_bxwhoami@$sl_bxmachine) Idle [expr [unixtime] - $sl_bxjointime] seconds\001"
354     return 1
355     }
356     "PING" {
357     putserv "NOTICE $nick :\001PING $arg\001"
358     return 1
359     }
360     "ECHO" {
361     if {[validchan $chan]} {return 1}
362     putserv "NOTICE $nick :\001ECHO [string range $arg 0 59]\001"
363     return 1
364     }
365     "ERRMSG" {
366     if {[validchan $chan]} {return 1}
367     putserv "NOTICE $nick :\001ERRMSG [string range $arg 0 59]\001"
368     return 1
369     }
370     "INVITE" {
371 guppy 1.2 if {$arg == "" || [validchan $chan]} {return 1}
372 guppy 1.1 set chanarg [lindex [split $arg] 0]
373     if {((($sl_bxversion == "75p1+") && ([string trim [string index $chanarg 0] "#+&"] == "")) || (($sl_bxversion == "75p3+") && ([string trim [string index $chanarg 0] "#+&!"] == "")))} {
374     if {[validchan $chanarg]} {
375     putserv "NOTICE $nick :\002BitchX\002: Access Denied"
376     } else {
377     putserv "NOTICE $nick :\002BitchX\002: I'm not on that channel"
378     }
379     }
380     return 1
381     }
382     "WHOAMI" {
383     if {[validchan $chan]} {return 1}
384     putserv "NOTICE $nick :\002BitchX\002: Access Denied"
385     return 1
386     }
387     "OP" -
388     "OPS" {
389 guppy 1.2 if {$arg == "" || [validchan $chan]} {return 1}
390 guppy 1.1 putserv "NOTICE $nick :\002BitchX\002: I'm not on [lindex [split $arg] 0], or I'm not opped"
391     return 1
392     }
393     "UNBAN" {
394 guppy 1.2 if {$arg == "" || [validchan $chan]} {return 1}
395 guppy 1.1 if {[validchan [lindex [split $arg] 0]]} {
396     putserv "NOTICE $nick :\002BitchX\002: Access Denied"
397     } else {
398     putserv "NOTICE $nick :\002BitchX\002: I'm not on that channel"
399     }
400     return 1
401     }
402     }
403     return 0
404     }
405    
406     proc sl_bmflood {nick uhost hand text} {
407     global sl_bmflood sl_bflooded sl_bmqueue sl_note
408 guppy 1.2 if {[matchattr $hand b] && [string tolower [lindex [split $text] 0]] == "go"} {return 0}
409 guppy 1.1 if {$sl_bflooded} {
410 guppy 1.2 sl_ignore [string tolower $uhost] $hand "MSG flooder" ; return 0
411 guppy 1.1 }
412     incr sl_bmqueue
413 wcc 1.4 utimer [lindex $sl_bmflood 1] {incr sl_bmqueue -1}
414 guppy 1.1 if {$sl_bmqueue >= [lindex $sl_bmflood 0]} {
415     putlog "sentinel: MSG flood detected on me! Stopped answering MSGs temporarily."
416     set sl_bflooded 1
417 wcc 1.4 utimer [lindex $sl_bmflood 1] {set sl_bflooded 0}
418 guppy 1.1 if {[info commands sendnote] != ""} {
419     foreach recipient $sl_note {
420     if {[validuser $recipient]} {
421     sendnote SENTINEL $recipient "Bot was MSG flooded."
422     }
423     }
424     }
425     }
426     return 0
427     }
428    
429     proc sl_avflood {from keyword arg} {
430     global botnet-nick botnick sl_ban sl_avbanhost sl_avbannick sl_avflood sl_avqueue sl_flooded sl_locked sl_txflood sl_txqueue
431     set arg [split $arg]
432     set chan [string tolower [lindex $arg 0]]
433     if {![validchan $chan]} {return 0}
434     set nick [lindex [split $from !] 0]
435 guppy 1.2 if {$nick == $botnick || $nick == "" || [string match *.* $nick]} {return 0}
436     if {![onchan $nick $chan] || [isop $nick $chan]} {return 0}
437     if {!$sl_flooded($chan) && [lsearch -exact $sl_txflood 0] == -1} {
438 guppy 1.1 incr sl_txqueue($chan)
439     if {$sl_txqueue($chan) >= [lindex $sl_txflood 0]} {
440     sl_lock $chan "TEXT flood" ${botnet-nick}
441     }
442     }
443     set text [join [lrange $arg 1 end]]
444 guppy 1.2 if {[sl_checkaval $text] && [lsearch -exact $sl_avflood 0] == -1} {
445 guppy 1.1 set uhost [string trimleft [getchanhost $nick $chan] "~+-^="]
446     set hand [nick2hand $nick $chan]
447 guppy 1.2 if {$sl_ban && !$sl_locked($chan) && $nick != $botnick && ![matchattr $hand f|f $chan]} {
448     lappend sl_avbannick($chan) $nick ; lappend sl_avbanhost($chan) [string tolower $uhost]
449 wcc 1.4 utimer [lindex $sl_avflood 1] [list sl_avbanqueue $chan]
450 guppy 1.1 }
451     if {$sl_flooded($chan)} {return 0}
452     incr sl_avqueue($chan)
453 wcc 1.4 utimer [lindex $sl_avflood 1] [list sl_avqueuereset $chan]
454 guppy 1.1 if {$sl_avqueue($chan) >= [lindex $sl_avflood 0]} {
455 guppy 1.2 sl_lock $chan "AVALANCHE/TSUNAMI flood" ${botnet-nick}
456 guppy 1.1 }
457     }
458     return 0
459     }
460    
461     proc sl_checkaval {text} {
462 guppy 1.2 global sl_tsunami
463     if {[regsub -all -- "\001|\007" $text "" temp] >= 3} {return 1}
464     if {$sl_tsunami && [regsub -all -- "\002|\003|\017|\026|\037" $text "" temp] >= $sl_tsunami} {return 1}
465 guppy 1.1 return 0
466     }
467    
468     proc sl_nkflood {nick uhost hand chan newnick} {
469     global botnet-nick botnick sl_ban sl_banmax sl_flooded sl_globalban sl_locked sl_nickkick sl_nkbanhost sl_nkflood sl_nkflooding sl_nkqueue
470     set chan [string tolower $chan]
471     if {[isop $newnick $chan]} {return 0}
472 guppy 1.2 if {$sl_ban && !$sl_locked($chan) && $nick != $botnick && ![matchattr $hand f|f $chan]} {
473     lappend sl_nkbanhost($chan) [string tolower $uhost]
474 wcc 1.4 utimer [lindex $sl_nkflood 1] [list sl_nkbanqueue $chan]
475 guppy 1.1 }
476 guppy 1.2 if {!$sl_nickkick && $sl_flooded($chan) && $sl_locked($chan)} {
477 guppy 1.1 putserv "KICK $chan $newnick :NICK flooder"
478     set sl_nickkick 1 ; set sl_nkflooding($chan) [unixtime]
479     if {$sl_ban} {
480 wcc 1.4 set bhost [string tolower [sl_masktype $uhost]]
481 guppy 1.1 if {$sl_globalban} {
482 guppy 1.3 if {[llength [banlist]] < $sl_banmax && ![isban $bhost] && ![matchban $bhost]} {
483 guppy 1.1 newban $bhost sentinel "NICK flooder" $sl_ban
484     }
485     } else {
486 guppy 1.3 if {[llength [banlist $chan]] < $sl_banmax && ![isban $bhost $chan] && ![matchban $bhost $chan]} {
487 guppy 1.1 newchanban $chan $bhost sentinel "NICK flooder" $sl_ban
488     }
489     }
490     }
491 wcc 1.4 utimer [expr [rand 2] + 3] {set sl_nickkick 0}
492 guppy 1.1 return 0
493     }
494     if {$sl_flooded($chan)} {return 0}
495     incr sl_nkqueue($chan)
496 wcc 1.4 utimer [lindex $sl_nkflood 1] [list sl_nkqueuereset $chan]
497 guppy 1.1 if {$sl_nkqueue($chan) >= [lindex $sl_nkflood 0]} {
498     sl_lock $chan "NICK flood" ${botnet-nick}
499     }
500     return 0
501     }
502    
503     proc sl_jflood {nick uhost hand chan} {
504     global botnet-nick botnick sl_ban sl_banmax sl_boban sl_bobanhost sl_bobannick sl_boflood sl_boqueue sl_flooded sl_globalban sl_jbanhost sl_jbannick sl_jflood sl_jqueue sl_locked sl_pqueue
505     if {$nick == $botnick} {
506     sl_setarray $chan
507     } else {
508 wcc 1.4 set ihost [string tolower [sl_masktype $uhost]]
509 guppy 1.1 if {[isignore $ihost]} {
510     killignore $ihost
511     }
512     set chan [string tolower $chan]
513 guppy 1.2 if {[lsearch -exact $sl_boflood 0] == -1 && [sl_checkbogus [lindex [split $uhost @] 0]]} {
514     if {!$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
515 wcc 1.4 set bhost [string tolower [sl_masktype $uhost]]
516 guppy 1.2 if {$sl_boban && [botisop $chan] && !$sl_flooded($chan)} {
517 guppy 1.1 putserv "KICK $chan $nick :BOGUS username"
518     if {$sl_globalban} {
519 guppy 1.3 if {[llength [banlist]] < $sl_banmax && ![isban $bhost] && ![matchban $bhost]} {
520 guppy 1.1 newban $bhost sentinel "BOGUS username" $sl_boban
521     }
522     } else {
523 guppy 1.3 if {[llength [banlist $chan]] < $sl_banmax && ![isban $bhost $chan] && ![matchban $bhost $chan]} {
524 guppy 1.1 newchanban $chan $bhost sentinel "BOGUS username" $sl_boban
525     }
526     }
527     }
528     if {$sl_ban} {
529 guppy 1.2 lappend sl_bobannick($chan) $nick ; lappend sl_bobanhost($chan) [string tolower $uhost]
530 wcc 1.4 utimer [lindex $sl_boflood 1] [list sl_bobanqueue $chan]
531 guppy 1.1 }
532     }
533     if {!$sl_flooded($chan)} {
534     incr sl_boqueue($chan)
535 wcc 1.4 utimer [lindex $sl_boflood 1] [list sl_boqueuereset $chan]
536 guppy 1.1 if {$sl_boqueue($chan) >= [lindex $sl_boflood 0]} {
537     sl_lock $chan "BOGUS joins" ${botnet-nick}
538     }
539     }
540     }
541     if {[lsearch -exact $sl_jflood 0] == -1} {
542 guppy 1.2 if {$sl_ban && !$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
543     lappend sl_jbannick($chan) $nick ; lappend sl_jbanhost($chan) [string tolower $uhost]
544 wcc 1.4 utimer [lindex $sl_jflood 1] [list sl_jbanqueue $chan]
545 guppy 1.1 }
546     if {$sl_flooded($chan)} {return 0}
547     incr sl_jqueue($chan)
548 wcc 1.4 utimer [lindex $sl_jflood 1] [list sl_jqueuereset $chan]
549 guppy 1.2 if {$sl_jqueue($chan) >= [lindex $sl_jflood 0] && $sl_pqueue($chan) >= [lindex $sl_jflood 0]} {
550 guppy 1.1 sl_lock $chan "JOIN-PART flood" ${botnet-nick}
551     }
552     }
553     }
554     return 0
555     }
556    
557     proc sl_checkbogus {ident} {
558     if {[regsub -all -- "\[^\041-\176\]" $ident "" temp] >= 1} {return 1}
559     return 0
560     }
561    
562     proc sl_pflood {nick uhost hand chan {msg ""}} {
563     global botnick sl_ban sl_flooded sl_jflood sl_locked sl_pbanhost sl_pbannick sl_pqueue
564     if {[lsearch -exact $sl_jflood 0] != -1} {return 0}
565 guppy 1.2 if {$nick == $botnick} {
566     if {![validchan $chan]} {
567 wcc 1.4 timer 5 [list sl_unsetarray $chan]
568 guppy 1.2 }
569     return 0
570     }
571 guppy 1.1 set chan [string tolower $chan]
572 guppy 1.2 if {$sl_ban && !$sl_locked($chan) && ![matchattr $hand f|f $chan]} {
573     lappend sl_pbannick($chan) $nick ; lappend sl_pbanhost($chan) [string tolower $uhost]
574 wcc 1.4 utimer [lindex $sl_jflood 1] [list sl_pbanqueue $chan]
575 guppy 1.1 }
576     if {$sl_flooded($chan)} {return 0}
577     incr sl_pqueue($chan)
578 wcc 1.4 utimer [lindex $sl_jflood 1] [list sl_pqueuereset $chan]
579 guppy 1.1 return 0
580     }
581    
582     proc sl_pfloodk {nick uhost hand chan kicked reason} {
583     global botnick sl_flooded sl_jflood sl_pqueue
584     if {[lsearch -exact $sl_jflood 0] != -1} {return 0}
585     if {$kicked == $botnick} {return 0}
586     set chan [string tolower $chan]
587     if {$sl_flooded($chan)} {return 0}
588     incr sl_pqueue($chan)
589 wcc 1.4 utimer [lindex $sl_jflood 1] [list sl_pqueuereset $chan]
590 guppy 1.1 return 0
591     }
592    
593     proc sl_lock {chan flood detected} {
594     global botnet-nick sl_bflooded sl_cfnotice sl_flooded sl_ilocktime sl_mlocktime sl_note
595 wcc 1.4 if {[string tolower $detected] == [string tolower ${botnet-nick}]} {
596 guppy 1.1 set sl_flooded($chan) 1 ; set sl_bflooded 1
597     if {[botisop $chan]} {
598 guppy 1.2 sl_quicklock $chan
599 guppy 1.1 sl_killutimer "sl_unlock $chan *"
600     sl_killutimer "set sl_bflooded 0"
601     if {$sl_mlocktime} {
602 wcc 1.4 utimer $sl_mlocktime [list sl_unlock $chan m]
603 guppy 1.1 }
604     if {$sl_ilocktime} {
605 wcc 1.4 utimer $sl_ilocktime [list sl_unlock $chan i]
606 guppy 1.1 }
607 wcc 1.4 utimer 120 {set sl_bflooded 0}
608 guppy 1.1 putlog "sentinel: $flood detected on $chan! Channel locked temporarily."
609     if {$sl_cfnotice != ""} {
610     puthelp "NOTICE $chan :$sl_cfnotice"
611     }
612     } else {
613     putlog "sentinel: $flood detected on $chan! Cannot lock channel because I'm not opped."
614 wcc 1.4 utimer 120 {set sl_bflooded 0}
615 guppy 1.1 }
616     } else {
617     putlog "sentinel: $flood detected by $detected on $chan!"
618     }
619     if {[info commands sendnote] != ""} {
620     foreach recipient $sl_note {
621     if {[validuser $recipient]} {
622 wcc 1.4 if {[string tolower $detected] == [string tolower ${botnet-nick}]} {
623 guppy 1.1 sendnote SENTINEL $recipient "$flood detected on $chan."
624     } else {
625     sendnote SENTINEL $recipient "$flood detected by $detected on $chan."
626     }
627     }
628     }
629     }
630     return 0
631     }
632    
633     proc sl_unlock {chan umode} {
634     global sl_bflooded sl_bfmaxbans sl_flooded sl_ilocktime sl_mlocktime sl_nkflooding
635     if {[expr [unixtime] - $sl_nkflooding($chan)] < 12} {
636     putlog "sentinel: nick flooding still in progress on $chan - not removing +mi yet.."
637     set sl_flooded($chan) 1 ; set sl_bflooded 1
638     sl_killutimer "sl_unlock $chan *"
639     sl_killutimer "set sl_bflooded 0"
640 wcc 1.4 utimer $sl_mlocktime [list sl_unlock $chan m] ; utimer $sl_ilocktime [list sl_unlock $chan i]
641     utimer 120 {set sl_bflooded 0}
642 guppy 1.1 } else {
643     set sl_flooded($chan) 0
644     if {![botisop $chan]} {return 0}
645     if {$umode == "mi"} {
646     putlog "sentinel: flood was small, performing early unlock.."
647     }
648 guppy 1.2 if {[string match *i* $umode] && [string match *i* [lindex [split [getchanmode $chan]] 0]]} {
649     if {$sl_bfmaxbans && [llength [chanbans $chan]] >= $sl_bfmaxbans} {
650 guppy 1.1 putlog "sentinel: not removing +i on $chan due to full ban list."
651     } else {
652     pushmode $chan -i
653     putlog "sentinel: removed +i on $chan"
654     }
655     }
656 guppy 1.2 if {[string match *m* $umode] && [string match *m* [lindex [split [getchanmode $chan]] 0]]} {
657 guppy 1.1 pushmode $chan -m
658     putlog "sentinel: removed +m on $chan"
659     }
660     }
661     return 0
662     }
663    
664     proc sl_mode {nick uhost hand chan mode victim} {
665     global botnick sl_ban sl_bfmaxbans sl_bfnotice sl_bfull sl_flooded sl_locked sl_note sl_unlocked
666     set chan [string tolower $chan]
667 guppy 1.2 if {$mode == "+b" && $sl_bfmaxbans && !$sl_bfull($chan) && ![string match *i* [lindex [split [getchanmode $chan]] 0]] && [botisop $chan] && [llength [chanbans $chan]] >= $sl_bfmaxbans} {
668 guppy 1.1 putserv "MODE $chan +i"
669     set sl_bfull($chan) 1
670 wcc 1.4 utimer 5 [list set sl_bfull($chan) 0]
671 guppy 1.1 putlog "sentinel: locked $chan due to full ban list!"
672     if {$sl_bfnotice != ""} {
673     puthelp "NOTICE $chan :$sl_bfnotice"
674     }
675     if {[info commands sendnote] != ""} {
676     foreach recipient $sl_note {
677     if {[validuser $recipient]} {
678     sendnote SENTINEL $recipient "Locked $chan due to full ban list."
679     }
680     }
681     }
682 guppy 1.2 } elseif {$mode == "+i" && $sl_flooded($chan)} {
683 guppy 1.1 set sl_locked($chan) 1
684     if {$sl_ban} {
685     sl_killutimer "sl_*banqueue $chan"
686 wcc 1.4 utimer 7 [list sl_dokicks $chan] ; utimer 16 [list sl_setbans $chan]
687 guppy 1.1 }
688 guppy 1.2 } elseif {$mode == "-i" || $mode == "-m"} {
689 guppy 1.1 set sl_locked($chan) 0
690     set sl_unlocked($chan) [unixtime]
691     if {$sl_flooded($chan)} {
692     set sl_flooded($chan) 0
693     if {$mode == "-i"} {
694     sl_killutimer "sl_unlock $chan i"
695     } else {
696     sl_killutimer "sl_unlock $chan m"
697     }
698     sl_killutimer "sl_unlock $chan mi"
699     if {$nick != $botnick} {
700     putlog "sentinel: $chan unlocked by $nick"
701     }
702     }
703     }
704     return 0
705     }
706    
707     proc sl_dokicks {chan} {
708     global sl_avbannick sl_bobannick sl_ccbannick sl_kflooders sl_jbannick sl_pbannick
709 guppy 1.2 if {![botisop $chan]} {return 0}
710 guppy 1.1 set sl_kflooders 0
711     sl_kick $chan $sl_ccbannick($chan) "CTCP flooder" ; set sl_ccbannick($chan) ""
712 guppy 1.2 sl_kick $chan $sl_avbannick($chan) "AVALANCHE/TSUNAMI flooder" ; set sl_avbannick($chan) ""
713 guppy 1.1 sl_kick $chan $sl_bobannick($chan) "BOGUS username" ; set sl_bobannick($chan) ""
714     set jklist $sl_jbannick($chan) ; set pklist $sl_pbannick($chan)
715 guppy 1.2 if {$jklist != "" && $pklist != ""} {
716 guppy 1.1 set klist ""
717     foreach nick $jklist {
718     if {[lsearch -exact $pklist $nick] != -1} {
719     lappend klist $nick
720     }
721     }
722     sl_kick $chan $klist "JOIN-PART flooder"
723     }
724     set sl_jbannick($chan) "" ; set sl_pbannick($chan) ""
725     return 0
726     }
727    
728     proc sl_kick {chan klist reason} {
729     global sl_kflooders sl_kicks
730     if {$klist != ""} {
731     set kicklist ""
732     foreach nick $klist {
733     if {[lsearch -exact $kicklist $nick] == -1} {
734     lappend kicklist $nick
735     }
736     }
737     unset nick
738     incr sl_kflooders [llength $kicklist]
739     foreach nick $kicklist {
740 guppy 1.2 if {[onchan $nick $chan] && ![onchansplit $nick $chan]} {
741 guppy 1.1 lappend ksend $nick
742     if {[llength $ksend] >= $sl_kicks} {
743     putserv "KICK $chan [join $ksend ,] :$reason"
744     unset ksend
745     }
746     }
747     }
748     if {[info exists ksend]} {
749     putserv "KICK $chan [join $ksend ,] :$reason"
750     }
751     }
752     return 0
753     }
754    
755     proc sl_setbans {chan} {
756 guppy 1.3 global sl_avbanhost sl_bobanhost sl_ccbanhost sl_kflooders sl_jbanhost sl_nkbanhost sl_pbanhost sl_shortlock sl_unlocked sl_wideban
757 guppy 1.1 if {![botonchan $chan]} {return 0}
758 guppy 1.2 set sl_ccbanhost($chan) [sl_dfilter $sl_ccbanhost($chan)]
759     set sl_avbanhost($chan) [sl_dfilter $sl_avbanhost($chan)]
760     set sl_nkbanhost($chan) [sl_dfilter $sl_nkbanhost($chan)]
761     set sl_bobanhost($chan) [sl_dfilter $sl_bobanhost($chan)]
762     set sl_jbanhost($chan) [sl_dfilter $sl_jbanhost($chan)]
763     set sl_pbanhost($chan) [sl_dfilter $sl_pbanhost($chan)]
764 guppy 1.3 set blist ""
765 guppy 1.2 if {$sl_jbanhost($chan) != "" && $sl_pbanhost($chan) != ""} {
766     foreach bhost $sl_jbanhost($chan) {
767     if {[lsearch -exact $sl_pbanhost($chan) $bhost] != -1} {
768 guppy 1.1 lappend blist $bhost
769     }
770     }
771     }
772 wcc 1.4 set allbans [sl_dfilter [concat $sl_ccbanhost($chan) $sl_avbanhost($chan) $sl_nkbanhost($chan) $sl_bobanhost($chan) $blist]]
773 guppy 1.3 if {$sl_wideban} {
774     sl_ban $chan [sl_dcheck $allbans] "MULTIPLE IDENT/HOST flooders"
775     }
776     sl_ban $chan $sl_ccbanhost($chan) "CTCP flooder" ; set sl_ccbanhost($chan) ""
777     sl_ban $chan $sl_avbanhost($chan) "AVALANCHE/TSUNAMI flooder" ; set sl_avbanhost($chan) ""
778     sl_ban $chan $sl_nkbanhost($chan) "NICK flooder" ; set sl_nkbanhost($chan) ""
779     sl_ban $chan $sl_bobanhost($chan) "BOGUS username" ; set sl_bobanhost($chan) ""
780     sl_ban $chan $blist "JOIN-PART flooder"
781 guppy 1.1 set sl_jbanhost($chan) "" ; set sl_pbanhost($chan) ""
782 guppy 1.2 if {$sl_shortlock && $sl_kflooders <= 2 && [llength $allbans] <= 2 && [expr [unixtime] - $sl_unlocked($chan)] > 120} {
783 guppy 1.1 sl_killutimer "sl_unlock $chan *"
784 wcc 1.4 utimer 10 [list sl_unlock $chan mi]
785 guppy 1.1 }
786     return 0
787     }
788    
789 guppy 1.2 proc sl_dfilter {list} {
790     set newlist ""
791     foreach item $list {
792     if {[lsearch -exact $newlist $item] == -1} {
793     lappend newlist $item
794     }
795     }
796     return $newlist
797     }
798    
799     proc sl_dcheck {bhosts} {
800     set blist ""
801     foreach bhost $bhosts {
802 wcc 1.4 set baddr [lindex [split [maskhost $bhost] "@"] 1]
803     set bident [string trimleft [lindex [split $bhost "@"] 0] "~"]
804 guppy 1.2 if {![info exists baddrs($baddr)]} {
805     set baddrs($baddr) 1
806     } else {
807     incr baddrs($baddr)
808     }
809     if {![info exists bidents($bident)]} {
810     set bidents($bident) 1
811     } else {
812     incr bidents($bident)
813     }
814 wcc 1.4 }
815 guppy 1.2 foreach baddr [array names baddrs] {
816     if {$baddrs($baddr) >= 2} {
817 guppy 1.3 lappend blist *!*@$baddr
818 guppy 1.2 }
819     }
820     foreach bident [array names bidents] {
821     if {$bidents($bident) >= 2} {
822     lappend blist *!*$bident@*
823     }
824     }
825     return $blist
826     }
827    
828 guppy 1.1 proc sl_ban {chan blist reason} {
829 guppy 1.2 global sl_ban sl_banmax sl_globalban
830 guppy 1.1 if {$blist != ""} {
831     if {$sl_globalban} {
832 guppy 1.2 foreach bhost $blist {
833     if {![string match *!* $bhost]} {
834     if {[matchban *!$bhost]} {continue}
835 wcc 1.4 set bhost [sl_masktype $bhost]
836 guppy 1.2 if {[isban $bhost]} {continue}
837     } else {
838     if {[isban $bhost]} {continue}
839     foreach ban [banlist] {
840     if {[lindex $ban 5] == "sentinel" && [string match $bhost [string tolower [lindex $ban 0]]]} {
841     killban $ban
842     }
843     }
844     }
845 wcc 1.4 if {[llength [banlist]] >= $sl_banmax} {continue}
846 guppy 1.1 newban $bhost sentinel $reason $sl_ban
847     putlog "sentinel: banned $bhost ($reason)"
848     sl_ignore $bhost * $reason
849     }
850     } else {
851 guppy 1.2 foreach bhost $blist {
852     if {![string match *!* $bhost]} {
853     if {[matchban *!$bhost $chan]} {continue}
854 wcc 1.4 set bhost [sl_masktype $bhost]
855 guppy 1.2 if {[isban $bhost $chan]} {continue}
856     } else {
857     if {[isban $bhost $chan]} {continue}
858     foreach ban [banlist $chan] {
859     if {[lindex $ban 5] == "sentinel" && [string match $bhost [string tolower [lindex $ban 0]]]} {
860     killchanban $chan $ban
861     }
862     }
863     }
864 wcc 1.4 if {[llength [banlist $chan]] >= $sl_banmax} {continue}
865 guppy 1.1 newchanban $chan $bhost sentinel $reason $sl_ban
866     putlog "sentinel: banned $bhost on $chan ($reason)"
867     sl_ignore $bhost * $reason
868     }
869     }
870     }
871     return 0
872     }
873    
874 guppy 1.2 proc sl_ignore {ihost hand flood} {
875 guppy 1.1 global sl_igtime
876     if {$hand != "*"} {
877     foreach chan [channels] {
878     if {[matchattr $hand f|f $chan]} {return 0}
879     }
880     }
881 wcc 1.4 if {![string match *!* $ihost]} {
882 guppy 1.2 foreach ignore [ignorelist] {
883 wcc 1.4 if {[string match [string tolower [lindex $ignore 0]] $ihost]} {
884 guppy 1.2 return 0
885     }
886     }
887 wcc 1.4 set ihost [sl_masktype $ihost]
888 guppy 1.2 if {[isignore $ihost]} {return 0}
889     } else {
890     if {[isignore $ihost]} {return 0}
891     foreach ignore [ignorelist] {
892     if {[lindex $ignore 4] == "sentinel" && [string match $ihost [string tolower [lindex $ignore 0]]]} {
893     killignore $ignore
894     }
895     }
896     }
897 guppy 1.1 newignore $ihost sentinel $flood $sl_igtime
898     putlog "sentinel: added $ihost to ignore list ($flood)"
899 guppy 1.2 return 1
900 guppy 1.1 }
901    
902 wcc 1.4 # queuereset procs allow all queue timers to be killed easily
903 guppy 1.1 proc sl_ccqueuereset {chan} {
904     global sl_ccqueue
905     incr sl_ccqueue($chan) -1
906     return 0
907     }
908    
909     proc sl_bcqueuereset {} {
910     global sl_bcqueue
911     incr sl_bcqueue -1
912     return 0
913     }
914    
915     proc sl_bmqueuereset {} {
916     global sl_bmqueue
917     incr sl_bmqueue -1
918     return 0
919     }
920    
921     proc sl_avqueuereset {chan} {
922     global sl_avqueue
923     incr sl_avqueue($chan) -1
924     return 0
925     }
926    
927     proc sl_txqueuereset {} {
928     global sl_txqueue sl_txflood
929     foreach chan [string tolower [channels]] {
930     if {[info exists sl_txqueue($chan)]} {
931     set sl_txqueue($chan) 0
932     }
933     }
934     utimer [lindex $sl_txflood 1] sl_txqueuereset
935     return 0
936     }
937    
938     proc sl_nkqueuereset {chan} {
939     global sl_nkqueue
940     incr sl_nkqueue($chan) -1
941     return 0
942     }
943    
944     proc sl_boqueuereset {chan} {
945     global sl_boqueue
946     incr sl_boqueue($chan) -1
947     return 0
948     }
949    
950     proc sl_jqueuereset {chan} {
951     global sl_jqueue
952     incr sl_jqueue($chan) -1
953     return 0
954     }
955    
956     proc sl_pqueuereset {chan} {
957     global sl_pqueue
958     incr sl_pqueue($chan) -1
959     return 0
960     }
961    
962     proc sl_ccbanqueue {chan} {
963     global sl_ccbanhost sl_ccbannick
964     set sl_ccbannick($chan) [lrange sl_ccbannick($chan) 1 end] ; set sl_ccbanhost($chan) [lrange sl_ccbanhost($chan) 1 end]
965     return 0
966     }
967    
968     proc sl_avbanqueue {chan} {
969     global sl_avbanhost sl_avbannick
970     set sl_avbannick($chan) [lrange sl_avbannick($chan) 1 end] ; set sl_avbanhost($chan) [lrange sl_avbanhost($chan) 1 end]
971     return 0
972     }
973    
974     proc sl_nkbanqueue {chan} {
975     global sl_nkbanhost
976     set sl_nkbanhost($chan) [lrange sl_nkbanhost($chan) 1 end]
977     return 0
978     }
979    
980     proc sl_bobanqueue {chan} {
981     global sl_bobanhost sl_bobannick
982     set sl_bobannick($chan) [lrange sl_bobannick($chan) 1 end] ; set sl_bobanhost($chan) [lrange sl_bobanhost($chan) 1 end]
983     return 0
984     }
985    
986     proc sl_jbanqueue {chan} {
987     global sl_jbanhost sl_jbannick
988     set sl_jbannick($chan) [lrange sl_jbannick($chan) 1 end] ; set sl_jbanhost($chan) [lrange sl_jbanhost($chan) 1 end]
989     return 0
990     }
991    
992     proc sl_pbanqueue {chan} {
993     global sl_pbanhost sl_pbannick
994     set sl_pbannick($chan) [lrange sl_pbannick($chan) 1 end] ; set sl_pbanhost($chan) [lrange sl_pbanhost($chan) 1 end]
995     return 0
996     }
997    
998     proc sl_flud {nick uhost hand type chan} {
999     global sl_flooded
1000     set chan [string tolower $chan]
1001 guppy 1.2 if {[validchan $chan] && $sl_flooded($chan)} {return 1}
1002 guppy 1.1 return 0
1003     }
1004    
1005     proc sl_lc {nick uhost hand chan arg} {
1006     global sl_lockcmds
1007     set chan [string tolower $chan]
1008     if {![botisop $chan]} {return 0}
1009 guppy 1.2 if {$sl_lockcmds == 2 && ![isop $nick $chan]} {return 0}
1010     sl_quicklock $chan
1011 guppy 1.1 putlog "sentinel: channel lock requested by $hand on $chan"
1012     return 0
1013     }
1014    
1015     proc sl_uc {nick uhost hand chan arg} {
1016     global sl_lockcmds
1017     set chan [string tolower $chan]
1018     if {![botisop $chan]} {return 0}
1019 guppy 1.2 if {$sl_lockcmds == 2 && ![isop $nick $chan]} {return 0}
1020 guppy 1.1 putserv "MODE $chan -mi"
1021     putlog "sentinel: channel unlock requested by $hand on $chan"
1022     return 0
1023     }
1024    
1025     proc sl_dcclc {hand idx arg} {
1026     global sl_lockflags
1027     putcmdlog "#$hand# lock $arg"
1028     set chan [lindex [split $arg] 0]
1029     if {$chan == "-all"} {
1030     if {![matchattr $hand $sl_lockflags]} {
1031     putidx $idx "You're not global +$sl_lockflags." ; return 0
1032     }
1033     set locklist ""
1034     foreach chan [channels] {
1035 guppy 1.2 if {[botisop $chan]} {
1036     sl_quicklock $chan
1037 guppy 1.1 lappend locklist $chan
1038     }
1039     }
1040     putidx $idx "Locked [join $locklist ", "]"
1041     } else {
1042     if {$chan == ""} {
1043     set chan [lindex [console $idx] 0]
1044     }
1045     if {![validchan $chan]} {
1046     putidx $idx "No such channel." ; return 0
1047     } elseif {![matchattr $hand $sl_lockflags|$sl_lockflags $chan]} {
1048     putidx $idx "You're not +$sl_lockflags on $chan." ; return 0
1049     } elseif {![botonchan $chan]} {
1050     putidx $idx "I'm not on $chan" ; return 0
1051     } elseif {![botisop $chan]} {
1052     putidx $idx "I'm not opped on $chan" ; return 0
1053     }
1054 guppy 1.2 sl_quicklock $chan
1055 guppy 1.1 putidx $idx "Locked $chan"
1056     }
1057     return 0
1058     }
1059    
1060     proc sl_dccuc {hand idx arg} {
1061     global sl_lockflags
1062     putcmdlog "#$hand# unlock $arg"
1063     set chan [lindex [split $arg] 0]
1064     if {$chan == "-all"} {
1065     if {![matchattr $hand $sl_lockflags]} {
1066     putidx $idx "You're not global +$sl_lockflags." ; return 0
1067     }
1068     set locklist ""
1069     foreach chan [channels] {
1070 guppy 1.2 if {[botisop $chan]} {
1071 guppy 1.1 putserv "MODE $chan -mi"
1072     lappend locklist $chan
1073     }
1074     }
1075     putidx $idx "Unlocked [join $locklist ", "]"
1076     } else {
1077     if {$chan == ""} {
1078     set chan [lindex [console $idx] 0]
1079     }
1080     if {![validchan $chan]} {
1081     putidx $idx "No such channel." ; return 0
1082     } elseif {![matchattr $hand $sl_lockflags|$sl_lockflags $chan]} {
1083     putidx $idx "You're not +$sl_lockflags on $chan." ; return 0
1084     } elseif {![botonchan $chan]} {
1085     putidx $idx "I'm not on $chan" ; return 0
1086     } elseif {![botisop $chan]} {
1087     putidx $idx "I'm not opped on $chan" ; return 0
1088     }
1089     putserv "MODE $chan -mi"
1090     putidx $idx "Unlocked $chan"
1091     }
1092     return 0
1093     }
1094    
1095 guppy 1.2 proc sl_quicklock {chan} {
1096     global numversion
1097     if {$numversion < 1050000} {
1098     putquick "MODE $chan +mi"
1099     } else {
1100     putquick "MODE $chan +mi" -next
1101     }
1102     }
1103    
1104 guppy 1.1 proc sl_dcc {hand idx arg} {
1105 wcc 1.4 global sl_avflood sl_ban sl_banmax sl_bcflood sl_boban sl_boflood sl_bmflood sl_bxsimul sl_bfmaxbans sl_ccflood sl_detectquits sl_globalban sl_igtime sl_jflood sl_kicks sl_lockcmds sl_lockflags sl_ilocktime sl_mlocktime sl_nkflood sl_note sl_shortlock sl_tsunami sl_txflood
1106 guppy 1.1 putcmdlog "#$hand# sentinel $arg"
1107     putidx $idx "This bot is protected by sentinel.tcl by slennox"
1108     putidx $idx "Current settings"
1109     if {[lsearch -exact $sl_bcflood 0] != -1} {
1110     putidx $idx "- Bot CTCP flood: Off"
1111     } else {
1112     putidx $idx "- Bot CTCP flood: [lindex $sl_bcflood 0] in [lindex $sl_bcflood 1] secs"
1113     }
1114     if {[lsearch -exact $sl_bmflood 0] != -1} {
1115     putidx $idx "- Bot MSG flood: Off"
1116     } else {
1117     putidx $idx "- Bot MSG flood: [lindex $sl_bmflood 0] in [lindex $sl_bmflood 1] secs"
1118     }
1119     if {[lsearch -exact $sl_ccflood 0] != -1} {
1120     putidx $idx "- Channel CTCP flood: Off"
1121     } else {
1122     putidx $idx "- Channel CTCP flood: [lindex $sl_ccflood 0] in [lindex $sl_ccflood 1] secs"
1123     }
1124     if {[lsearch -exact $sl_avflood 0] != -1} {
1125     putidx $idx "- Channel AVALANCHE flood: Off"
1126     } else {
1127     putidx $idx "- Channel AVALANCHE flood: [lindex $sl_avflood 0] in [lindex $sl_avflood 1] secs"
1128     }
1129 guppy 1.2 if {[lsearch -exact $sl_avflood 0] != -1 || !$sl_tsunami} {
1130     putidx $idx "- Channel TSUNAMI flood: Off"
1131     } else {
1132     putidx $idx "- Channel TSUNAMI flood: [lindex $sl_avflood 0] in [lindex $sl_avflood 1] secs ($sl_tsunami ctrl codes / line)"
1133     }
1134 guppy 1.1 if {[lsearch -exact $sl_txflood 0] != -1} {
1135     putidx $idx "- Channel TEXT flood: Off"
1136     } else {
1137     putidx $idx "- Channel TEXT flood: [lindex $sl_txflood 0] in [lindex $sl_txflood 1] secs"
1138     }
1139     if {[lsearch -exact $sl_boflood 0] != -1} {
1140     putidx $idx "- Channel BOGUS flood: Off"
1141     } else {
1142     putidx $idx "- Channel BOGUS flood: [lindex $sl_boflood 0] in [lindex $sl_boflood 1] secs"
1143     }
1144 wcc 1.4 if {$sl_detectquits} {
1145     set detectquits "quit detection ON"
1146     } else {
1147     set detectquits "quit detection OFF"
1148     }
1149 guppy 1.1 if {[lsearch -exact $sl_jflood 0] != -1} {
1150     putidx $idx "- Channel JOIN-PART flood: Off"
1151     } else {
1152 wcc 1.4 putidx $idx "- Channel JOIN-PART flood: [lindex $sl_jflood 0] in [lindex $sl_jflood 1] secs ($detectquits)"
1153 guppy 1.1 }
1154     if {[lsearch -exact $sl_nkflood 0] != -1} {
1155     putidx $idx "- Channel NICK flood: Off"
1156     } else {
1157     putidx $idx "- Channel NICK flood: [lindex $sl_nkflood 0] in [lindex $sl_nkflood 1] secs"
1158     }
1159     if {!$sl_ilocktime} {
1160     putidx $idx "- Channel +i locktime: Indefinite"
1161     } else {
1162     putidx $idx "- Channel +i locktime: $sl_ilocktime secs"
1163     }
1164     if {!$sl_mlocktime} {
1165     putidx $idx "- Channel +m locktime: Indefinite"
1166     } else {
1167     putidx $idx "- Channel +m locktime: $sl_mlocktime secs"
1168     }
1169 guppy 1.2 if {$sl_shortlock && $sl_ban} {
1170 guppy 1.1 putidx $idx "- Small flood short lock: Active"
1171     } else {
1172     putidx $idx "- Small flood short lock: Inactive"
1173     }
1174 guppy 1.2 if {$sl_ban && $sl_ban < 120} {
1175 guppy 1.1 putidx $idx "- Channel flood bans: $sl_ban mins"
1176     } elseif {$sl_ban >= 120} {
1177     putidx $idx "- Channel flood bans: [expr $sl_ban / 60] hrs"
1178     } else {
1179     putidx $idx "- Channel flood bans: Disabled"
1180     }
1181 guppy 1.2 if {!$sl_boban || [lsearch -exact $sl_boflood 0] != -1} {
1182 guppy 1.1 putidx $idx "- Bogus username bans: Disabled"
1183 guppy 1.2 } elseif {$sl_boban > 0 && $sl_boban < 120} {
1184 guppy 1.1 putidx $idx "- Bogus username bans: $sl_boban mins"
1185     } elseif {$sl_boban >= 120} {
1186     putidx $idx "- Bogus username bans: [expr $sl_boban / 60] hrs"
1187     }
1188 guppy 1.2 if {$sl_ban || [lsearch -exact $sl_boflood 0] == -1} {
1189 guppy 1.1 if {$sl_globalban} {
1190 wcc 1.4 putidx $idx "- Ban type: Global [sl_masktype nick@host.domain]"
1191 guppy 1.1 } else {
1192 wcc 1.4 putidx $idx "- Ban type: Channel-specific [sl_masktype nick@host.domain]"
1193 guppy 1.1 }
1194     }
1195 guppy 1.2 if {$sl_ban || [lsearch -exact $sl_boflood 0] == -1} {
1196 guppy 1.1 putidx $idx "- Maximum bans: $sl_banmax"
1197     }
1198 guppy 1.2 if {$sl_igtime > 0 && $sl_igtime < 120} {
1199 guppy 1.1 putidx $idx "- Flooder ignores: $sl_igtime mins"
1200     } elseif {$sl_igtime >= 120} {
1201     putidx $idx "- Flooder ignores: [expr $sl_igtime / 60] hrs"
1202     } else {
1203     putidx $idx "- Flooder ignores: Permanent"
1204     }
1205     if {$sl_ban} {
1206     putidx $idx "- Kicks per line: $sl_kicks"
1207     }
1208     if {!$sl_bfmaxbans} {
1209     putidx $idx "- Maximum channel bans: Disabled"
1210     } else {
1211     putidx $idx "- Maximum channel bans: $sl_bfmaxbans"
1212     }
1213     if {$sl_note != ""} {
1214     putidx $idx "- Flood notification: Notifying [join $sl_note ", "]"
1215     } else {
1216     putidx $idx "- Flood notification: Off"
1217     }
1218     if {!$sl_lockcmds} {
1219     putidx $idx "- Public lc/uc commands: Disabled"
1220     } elseif {$sl_lockcmds == 1} {
1221     putidx $idx "- Public lc/uc commands: Enabled (+$sl_lockflags users, ops not required)"
1222     } elseif {$sl_lockcmds == 2} {
1223     putidx $idx "- Public lc/uc commands: Enabled (+$sl_lockflags users, ops required)"
1224     }
1225     if {$sl_bxsimul} {
1226     putidx $idx "- BitchX simulation: On"
1227     } elseif {!$sl_bxsimul} {
1228     putidx $idx "- BitchX simulation: Off"
1229     }
1230     return 0
1231     }
1232    
1233     if {$sl_bxsimul} {
1234     bind raw - 001 sl_bxserverjoin
1235     if {![info exists sl_bxonestack]} {
1236     set sl_bxonestack 0
1237     }
1238     if {![info exists sl_bxversion]} {
1239     set sl_bxversion [lindex {75p1+ 75p3+} [rand 2]]
1240     }
1241     set sl_bxsystem "*IX" ; set sl_bxwhoami $username ; set sl_bxmachine ""
1242     catch {set sl_bxsystem [exec uname -s -r]}
1243     catch {set sl_bxwhoami [exec id -un]}
1244     catch {set sl_bxmachine [exec uname -n]}
1245     set sl_bxjointime [unixtime]
1246     proc sl_bxserverjoin {from keyword arg} {
1247     global sl_bxjointime sl_bxisaway
1248     set sl_bxjointime [unixtime] ; set sl_bxisaway 0
1249     return 0
1250     }
1251     proc sl_bxaway {} {
1252     global sl_bxjointime sl_bxisaway
1253     if {!$sl_bxisaway} {
1254     puthelp "AWAY :is away: (Auto-Away after 10 mins) \[\002BX\002-MsgLog [lindex {On Off} [rand 2]]\]"
1255     set sl_bxisaway 1
1256     } else {
1257     puthelp "AWAY"
1258     set sl_bxisaway 0 ; set sl_bxjointime [unixtime]
1259     }
1260     if {![string match *sl_bxaway* [timers]]} {
1261     timer [expr [rand 300] + 10] sl_bxaway
1262     }
1263     return 0
1264     }
1265     if {![info exists sl_bxisaway]} {
1266     set sl_bxisaway 0
1267     }
1268     if {![string match *sl_bxaway* [timers]]} {
1269     timer [expr [rand 300] + 10] sl_bxaway
1270     }
1271     }
1272    
1273     proc sl_setarray {chan} {
1274 guppy 1.2 global sl_avbanhost sl_avbannick sl_avqueue sl_bfull sl_bobanhost sl_bobannick sl_boqueue sl_ccbanhost sl_ccbannick sl_ccqueue sl_flooded sl_jbanhost sl_jbannick sl_jqueue sl_locked sl_nkbanhost sl_nkflooding sl_nkqueue sl_pbanhost sl_pbannick sl_pqueue sl_txqueue sl_unlocked
1275 guppy 1.1 set chan [string tolower $chan]
1276     sl_killutimer "incr sl_*queue($chan) -1"
1277     sl_killutimer "sl_*banqueue $chan"
1278 guppy 1.2 sl_killutimer "sl_*queuereset $chan"
1279 guppy 1.1 set sl_flooded($chan) 0 ; set sl_locked($chan) 0 ; set sl_unlocked($chan) [unixtime]
1280     set sl_nkflooding($chan) [unixtime]
1281     set sl_ccqueue($chan) 0 ; set sl_ccbanhost($chan) "" ; set sl_ccbannick($chan) ""
1282     set sl_avqueue($chan) 0 ; set sl_avbanhost($chan) "" ; set sl_avbannick($chan) ""
1283     set sl_txqueue($chan) 0
1284     set sl_nkqueue($chan) 0 ; set sl_nkbanhost($chan) ""
1285     set sl_boqueue($chan) 0 ; set sl_bobanhost($chan) "" ; set sl_bobannick($chan) ""
1286     set sl_jqueue($chan) 0 ; set sl_jbanhost($chan) "" ; set sl_jbannick($chan) ""
1287     set sl_pqueue($chan) 0 ; set sl_pbanhost($chan) "" ; set sl_pbannick($chan) ""
1288     set sl_bfull($chan) 0
1289     return 0
1290     }
1291    
1292 guppy 1.2 proc sl_unsetarray {chan} {
1293     global sl_avbanhost sl_avbannick sl_avqueue sl_bfull sl_bobanhost sl_bobannick sl_boqueue sl_ccbanhost sl_ccbannick sl_ccqueue sl_flooded sl_jbanhost sl_jbannick sl_jqueue sl_locked sl_nkbanhost sl_nkflooding sl_nkqueue sl_pbanhost sl_pbannick sl_pqueue sl_txqueue sl_unlocked
1294     set chan [string tolower $chan]
1295     if {![validchan $chan] && [info exists sl_flooded($chan)]} {
1296 wcc 1.4 unset sl_flooded($chan) sl_locked($chan) sl_unlocked($chan) sl_nkflooding($chan) sl_ccqueue($chan) sl_ccbanhost($chan) sl_ccbannick($chan) sl_avqueue($chan) sl_avbanhost($chan) sl_avbannick($chan) sl_txqueue($chan) sl_nkqueue($chan) sl_nkbanhost($chan) sl_boqueue($chan) sl_bobanhost($chan) sl_bobannick($chan) sl_jqueue($chan) sl_jbanhost($chan) sl_jbannick($chan) sl_pqueue($chan) sl_pbanhost($chan) sl_pbannick($chan) sl_bfull($chan)
1297 guppy 1.2 }
1298     return 0
1299     }
1300    
1301 guppy 1.1 proc sl_settimer {} {
1302     foreach chan [channels] {
1303     sl_setarray $chan
1304     }
1305     return 0
1306     }
1307    
1308     proc sl_killutimer {cmd} {
1309     set n 0
1310     regsub -all -- {\[} $cmd {\[} cmd ; regsub -all -- {\]} $cmd {\]} cmd
1311     foreach tmr [utimers] {
1312     if {[string match $cmd [join [lindex $tmr 1]]]} {
1313     killutimer [lindex $tmr 2]
1314     incr n
1315     }
1316     }
1317     return $n
1318     }
1319    
1320 wcc 1.4 proc sl_masktype {uhost} {
1321     global sl_masktype
1322     switch -exact -- $sl_masktype {
1323     0 {return *!*[string range $uhost [string first @ $uhost] end]}
1324     1 {return *!*$uhost}
1325     2 {return *!*[lindex [split [maskhost $uhost] "!"] 1]}
1326     }
1327     return
1328     }
1329    
1330 guppy 1.2 if {![info exists sl_unlocked] && ![string match *sl_settimer* [utimers]]} {
1331 guppy 1.1 utimer 3 sl_settimer
1332     }
1333    
1334     if {![info exists sl_bflooded]} {
1335     set sl_bflooded 0
1336     }
1337     if {![info exists sl_bcqueue]} {
1338     set sl_bcqueue 0
1339     }
1340     if {![info exists sl_bmqueue]} {
1341     set sl_bmqueue 0
1342     }
1343     if {![info exists sl_nickkick]} {
1344     set sl_nickkick 0
1345     }
1346    
1347     set sl_bcflood [split $sl_bcflood :] ; set sl_bmflood [split $sl_bmflood :]
1348     set sl_ccflood [split $sl_ccflood :] ; set sl_avflood [split $sl_avflood :]
1349     set sl_txflood [split $sl_txflood :] ; set sl_boflood [split $sl_boflood :]
1350     set sl_jflood [split $sl_jflood :] ; set sl_nkflood [split $sl_nkflood :]
1351     set sl_note [split $sl_note]
1352    
1353 guppy 1.2 if {$sl_ilocktime > 0 && $sl_ilocktime < 30} {
1354 guppy 1.1 set sl_ilocktime 30
1355     }
1356 guppy 1.2 if {$sl_mlocktime > 0 && $sl_mlocktime < 30} {
1357 guppy 1.1 set sl_mlocktime 30
1358     }
1359    
1360     set trigger-on-ignore 0
1361     if {!${kick-method}} {
1362     set sl_kicks 8
1363     } else {
1364     set sl_kicks ${kick-method}
1365     }
1366    
1367 guppy 1.2 if {$numversion <= 1040400} {
1368     if {$numversion >= 1032100} {
1369     set kick-bogus 0
1370     }
1371     if {$numversion >= 1032400} {
1372     set ban-bogus 0
1373     }
1374 guppy 1.1 }
1375     if {$numversion >= 1032400} {
1376 guppy 1.2 set kick-fun 0 ; set ban-fun 0
1377 guppy 1.1 }
1378     if {$numversion >= 1032500} {
1379     set ctcp-mode 0
1380     }
1381    
1382 guppy 1.2 if {![string match *sl_txqueuereset* [utimers]] && [lsearch -exact $sl_txflood 0] == -1} {
1383 guppy 1.1 utimer [lindex $sl_txflood 1] sl_txqueuereset
1384     }
1385    
1386     bind pub $sl_lockflags|$sl_lockflags lc sl_lc
1387     bind pub $sl_lockflags|$sl_lockflags uc sl_uc
1388     bind dcc $sl_lockflags|$sl_lockflags lock sl_dcclc
1389     bind dcc $sl_lockflags|$sl_lockflags unlock sl_dccuc
1390     if {!$sl_lockcmds} {
1391     unbind pub $sl_lockflags|$sl_lockflags lc sl_lc
1392 wcc 1.4 unbind pub $sl_lockflags|$sl_lockflags uc sl_uc
1393 guppy 1.3 rename sl_lc ""
1394     rename sl_uc ""
1395 guppy 1.1 }
1396     bind dcc m|m sentinel sl_dcc
1397     bind raw - NOTICE sl_avflood
1398     bind raw - PRIVMSG sl_avflood
1399 guppy 1.2 if {[lsearch -exact $sl_avflood 0] != -1 && [lsearch -exact $sl_txflood 0] != -1} {
1400 guppy 1.1 unbind raw - NOTICE sl_avflood
1401     unbind raw - PRIVMSG sl_avflood
1402 guppy 1.3 rename sl_avflood ""
1403 guppy 1.1 }
1404     bind ctcp - CLIENTINFO sl_ctcp
1405     bind ctcp - USERINFO sl_ctcp
1406     bind ctcp - VERSION sl_ctcp
1407     bind ctcp - FINGER sl_ctcp
1408     bind ctcp - ERRMSG sl_ctcp
1409     bind ctcp - ECHO sl_ctcp
1410     bind ctcp - INVITE sl_ctcp
1411     bind ctcp - WHOAMI sl_ctcp
1412     bind ctcp - OP sl_ctcp
1413     bind ctcp - OPS sl_ctcp
1414     bind ctcp - UNBAN sl_ctcp
1415     bind ctcp - PING sl_ctcp
1416     bind ctcp - TIME sl_ctcp
1417     bind msgm - * sl_bmflood
1418 guppy 1.3 if {[lsearch -exact $sl_bmflood 0] != -1} {
1419     unbind msgm - * sl_bmflood
1420     rename sl_bmflood ""
1421     }
1422 guppy 1.1 bind nick - * sl_nkflood
1423 guppy 1.3 if {[lsearch -exact $sl_nkflood 0] != -1} {
1424     unbind nick - * sl_nkflood
1425     rename sl_nkflood ""
1426     }
1427 guppy 1.1 bind join - * sl_jflood
1428     bind part - * sl_pflood
1429 wcc 1.4 bind sign - * sl_pflood
1430     if {![info exists sl_detectquits]} {
1431     set sl_detectquits 0
1432     }
1433     if {!$sl_detectquits} {
1434     unbind sign - * sl_pflood
1435     }
1436 guppy 1.1 bind kick - * sl_pfloodk
1437     bind flud - * sl_flud
1438     bind mode - * sl_mode
1439    
1440 wcc 1.4 putlog "Loaded sentinel.tcl v2.70 by slennox"
1441 guppy 1.1
1442     return

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23