eggdrop has this error:
Tcl error [clone_detect]: can't read "hand": no such variable
this is the script:
Code: Select all
# -- Configuration ------------------------------------------------------------
# "Fast-kick" - If your IRC server allows it, you can kick many people at once
# in just one command (I have tried it with 20 kicks on IRCnet). If you think
# this works on your irc network, set to "1", if not, set to "0".
# Here is what I got by testing on some networks:
# Dalnet - 0
# Efnet - 1
# IRCnet - 1
# Undernet - 0
set fastkick 0
# Is the whole clone-checking on or off by default?
# (use .clonecheck on/off to change while bot is running)
set clonecheck 1
# Hosts to except from clone-checking, wildcards (?*) allowed:
# - hosts which more than one users can use at the same time
# - hosts of your "friends" which are neither masters nor bots
# - hosts of bots on the channel which have no +b flag
# - etc etc
# Note: Use HOST, the thing after the users "@"
# e.g. "yo!yaba@yeba.edu" has host "yeba.edu"
set noclonehost {
}
# People with those flags are never clones: (Separate the list with spaces)
# Channel and Global flags are matched
set nocloneflag "b c m"
# How many minutes will a clone-host banning last
set clonebantime 2
# If this number of clones is reached, bot kicks and bans
set maxclone 1
# NOTICE other ops (if opped) when ANY clone joins/parts the channel? (0 = no)
# (for paranoid people only!)
set cloneopnotice 0
# -- Script -------------------------------------------------------------------
# A little proc to turn console +1 when a +m or +o joins:
bind chon - * dcc_on
proc dcc_on { hand idx } {
set cons1on 0
foreach chan [channels] {
if {[matchattr $hand m|m $chan] || [matchattr $hand o|o $chan]} {
set cons1on 1
}
}
if {$cons1on} { utimer 1 "console $idx -+1" }
return 0
}
# Opnotice proc, sends a notice to every op on a channel (if opped)
proc opnotice { chan text } {
global botnick
if {![botisop $chan]} { return 0 }
if {$text == ""} { return 0 }
# I set maxnicks to send the same NOTICE to maximal 10 nicks at the same
# time. Rise it if you want. (I don't know what the maximum IRC-allowed is)
set maxnicks 10
set oplist ""
set curnicks 0
foreach thisnick [chanlist $chan] {
# don't notice who's not op, the bot itself and other bots
if {([isop $thisnick $chan]) && ($thisnick != $botnick) && (![matchattr [nick2hand $thisnick $chan] b])} {
incr curnicks
# Add next op
lappend oplist $thisnick
# Reached maxnicks?
if {$curnicks == $maxnicks} {
# Send the text to the current list
regsub -all " " $oplist "," oplist
puthelp "NOTICE $oplist :$text"
# Clean up to begin next block
set curnicks 0
set oplist ""
}
}
}
if {$oplist != ""} {
# still some left to process
regsub -all " " $oplist "," oplist
puthelp "NOTICE $oplist :$text"
}
return 1
}
bind dcc m|m clones dcc_clone_stats
bind dcc m|m clonescheck dcc_clonecheck
bind dcc m|m clonecheck dcc_clonecheck
# Kicks users matching $mask from $chan. Uses "fastkick", if enabled.
# Returns a list of kicked users (may not have been executed, because of lag)
proc kickall { mask chan reason } {
global fastkick botnick nocloneflag
if {![validchan $chan]} { return "" }
set kicked ""
foreach thisnick [chanlist $chan] {
if {$thisnick == $botnick} { continue }
if {[string match "$mask" "$thisnick![getchanhost $thisnick $chan]"]} {
set dontkick 0
foreach exceptionflag $nocloneflag {
if {[matchattr $hand $exceptionflag|$exceptionflag $chan]} {
set dontkick 1
break
}
}
if {$dontkick} { continue }
if {[botisop $chan]} {
# We only can kick if we are op. But we want to return the list
# of "kicked" even if we aren't
if {$fastkick} {
lappend knick $thisnick
lappend kchan $chan
} {
putserv "KICK $chan $thisnick :$reason"
}
}
lappend kicked $thisnick
}
if {$fastkick && [info exist knick]} {
# Dump a KICK-line if it reaches 480 bytes
if {[string length "KICK $knick $kchan :$reason"] > 480} {
regsub -all " " $knick "," knick
regsub -all " " $kchan "," kchan
putserv "KICK $kchan $knick :$reason"
unset knick
unset kchan
}
}
}
if {$fastkick && [info exist knick]} {
regsub -all " " $knick "," knick
regsub -all " " $kchan "," kchan
putserv "KICK $kchan $knick :$reason"
}
return "$kicked"
}
# Goes through the channel user list, marking clones. Called 10 secs after a
# rehash/restart and 1 min after the bot joins the chan and after the bot is
# opped (to kick eventual unkicked clones)
proc set_clones { } {
global clonelist botnick maxclone fastkick
global noclonehost nocloneflag clonebantime
if [array exists clonelist] { unset clonelist }
foreach chan [channels] {
set chan [string tolower $chan]
set kicked ""
foreach nick [chanlist $chan] {
set hand [nick2hand $nick $chan]
if {[lsearch -exact $kicked $nick] >= 0} {
# This nick was already kicked
continue
}
set host [string tolower [lindex [split [getchanhost $nick $chan] @] 1]]
if [info exists clonelist($chan!$host)] {
incr clonelist($chan!$host) 1
if {$clonelist($chan!$host) >= $maxclone} {
newchanban $chan "*!*@$host" $botnick "Clones \($clonelist($chan!$host)\)" $clonebantime
set thiskicked [kickall "*!*@$host" $chan "Too many clones from $host"]
set kicked [concat $kicked $thiskicked]
putloglev 1 $chan "Max clones reached from $host in $chan: $thiskicked"
}
continue
}
set clonelist($chan!$host) 0
if {$nick == $botnick} {unset clonelist($chan!$host)}
foreach exceptionflag $nocloneflag {
if {[matchattr $hand $exceptionflag|$exceptionflag $chan]} {
if {[info exists clonelist($chan!$host)]} { unset clonelist($chan!$host) }
break
}
}
if {[info exists clonelist($chan!$host)]} {
foreach exceptionhost $noclonehost {
# remove it, if it is an exception
if {[string match [string tolower $exceptionhost] [string tolower $host]]} {
unset clonelist($chan!$host)
break
}
}
}
}
}
}
# (i love those 6-level identations...)
# Someone joining, check if this host already has someone here
proc clone_detect { nick uhost hand chan } {
global clonelist maxclone botnick
global nocloneflag noclonehost clonebantime cloneopnotice
set chan [string tolower $chan]
# It is me joining! Let's rescan the channels list for clones in 1 min!
if {$nick == $botnick} {
# previous timer exists, kill it, start a new one
foreach this [timers] {
if {[string compare [lindex $this 1] "set_clones"] == 0} {
killtimer [lindex $this 2]
}
}
timer 1 set_clones
return 0
}
# Someone joining. Check if bot needs to update cloneslist first
foreach this [timers] {
if {[string compare [lindex $this 1] "set_clones"] == 0} {
# Just relax, I need to refresh the clones-list first...
return 0
}
}
foreach exceptionflag $nocloneflag {
if {[matchattr $hand $exceptionflag|$exceptionflag $chan]} {
return 0
}
}
set host [string tolower [lindex [split $uhost @] 1]]
foreach exceptionhost $noclonehost {
# if it is an exception do nothing
if {[string match [string tolower $exceptionhost] $host]} {return 0}
}
if [info exists clonelist($chan!$host)] {
incr clonelist($chan!$host) 1
if {$clonelist($chan!$host) >= $maxclone} {
newchanban $chan "*!*@$host" $botnick "Cloni, espulsi per 5 minuti \($clonelist($chan!$host)\)" $clonebantime
set thiskicked [kickall "*!*@$host" $chan "Too many clones from $host"]
putloglev 1 $chan "Max clones reached from $host in $chan: $thiskicked"
return 1
}
foreach nick2 [chanlist $chan] {
set host2 [string tolower [lindex [split [getchanhost $nick2 $chan] @] 1]]
if {$host == $host2 && $nick != $nick2} { lappend clonenicks $nick2 }
}
regsub -all " " $clonenicks ", " clonenicks
if {$cloneopnotice} {
opnotice $chan "Clone IN: $nick \($uhost\) is a clone to $clonenicks in $chan"
}
putloglev 1 $chan "Clone IN $chan: $nick \($uhost\) is clone \#$clonelist($chan!$host) \($clonenicks\)"
return 1
}
set clonelist($chan!$host) 0
return 0
}
proc clone_remove { nick uhost hand chan { rest "" } } {
global clonelist botnick cloneopnotice nocloneflag noclonehost
set chan [string tolower $chan]
if {$nick == $botnick} {return 0}
foreach this [timers] {
if {[string compare [lindex $this 1] "set_clones"] == 0} {
# Just relax, I need to refresh the clones-list first...
return 0
}
}
set host [string tolower [lindex [split $uhost @] 1]]
foreach exceptionflag $nocloneflag {
if {[matchattr $hand $exceptionflag|$exceptionflag $chan]} {
return 0
}
}
foreach exceptionhost $noclonehost {
# if it is an exception do nothing
if {[string match [string tolower $exceptionhost] [string tolower $host]]} {return 0}
}
if ![info exists clonelist($chan!$host)] {return 0}
if {$clonelist($chan!$host) < 0} {
putloglev 1 $chan "Negative number of clones listed?? Something is wrong with the script!"
return 0
} elseif {$clonelist($chan!$host) == 0} {
unset clonelist($chan!$host)
return 1
} elseif {$clonelist($chan!$host) > 0} {
incr clonelist($chan!$host) -1
foreach n [chanlist $chan] {
set host2 [string tolower [lindex [split [getchanhost $n $chan] @] 1]]
if {($host == $host2) && ($n != $nick)} { lappend clonenicks $n }
}
regsub -all " " $clonenicks ", " clonenicks
putloglev 1 $chan "Clone OUT $chan: $nick \($uhost\) left \($clonenicks remaining\)"
if {$cloneopnotice} {
opnotice $chan "Clone OUT: $nick \($uhost\) left $chan \($clonenicks remaining\)"
}
return 1
}
}
proc clone_kick { nick host hand chan knick rest } {
clone_remove $knick [getchanhost $knick $chan] [nick2hand $knick $chan] $chan
}
proc clone_quit { nick host hand chan rest } {
clone_remove $nick $host $hand $chan
}
proc dcc_clonecheck { hand idx onoff } {
global clonecheck
set choice [string tolower $onoff]
if {$onoff == ""} {
if {$clonecheck} { set status "on" } { set status "off" }
putdcc $idx "Clone-checking currently \002${status}\002."
return 0
}
if {($choice != "on") && ($choice != "off")} {
putdcc $idx "Usage: '.clonecheck \[on/off\]'"
return 0
}
if {$choice == "on"} {
if {$clonecheck == 0} {
set clonecheck 1
putdcc $idx "Clone-checking is now \002on\002."
clonecheckload
return 1
} {
putdcc $idx "Clone-checking was already \002on\002."
return 0
}
} {
if {$clonecheck == 1} {
set clonecheck 0
putdcc $idx "Clone-checking is now \002off\002."
clonecheckload
return 1
} {
putdcc $idx "Clone-checking was already \002off\002."
return 0
}
}
}
proc dcc_clone_stats { hand idx chan } {
global clonecheck
if {$clonecheck == 0} {
putdcc $idx "Sorry, clone-checking currently off. Use \002.clonecheck on\002 to turn it on."
return 0
}
global clonelist
if {$chan == ""} {
set channel [lindex [console $idx] 0]
} {
regsub -nocase -all \[{}] $chan "" chan
set channel [lindex $chan 0]
}
putdcc $idx "Clones in $channel:"
set channel [string tolower $channel]
foreach addy [array names clonelist] {
if {$clonelist($addy) > 0} {
scan $addy "%\[^!]!%s" chan host
if {$chan != [string tolower $channel]} { continue }
foreach nick [chanlist $chan] {
set host2 [string tolower [lindex [split [getchanhost $nick $chan] @] 1]]
if {$host == $host2} { lappend clonenicks $nick }
}
}
if [info exists clonenicks] {
regsub -all " " $clonenicks ", " clonenicks
set clones($host) $clonenicks
unset clonenicks
}
}
if [array exists clones] {
set counter 0
foreach addy [array names clones] {
incr counter
putdcc $idx " $counter. $addy \($clones($addy)): $clonelist($channel!$addy)"
}
unset counter
} { putdcc $idx "No clones detected in $channel" }
return 1
}
proc clonecheckload {} {
global clonecheck clonelist clone_loaded
if {$clonecheck} {
# When activated, make all binds, and refresh clones-array
bind join - * clone_detect
bind part - * clone_remove
bind sign - * clone_quit
bind kick - * clone_kick
bind splt - * clone_remove
bind rejn - * clone_detect
set clone_loaded 1
# begins in 10 secs (not ON rehash, cause chan-userlist is not ok yet)
# if bot was restarted, set_clones is called 1 min after bot joins chan
# (see clone_detect)
utimer 10 set_clones
} {
# When not activated, remove all bindings and clean the clonelist from mem
if {$clone_loaded} {
unbind join - * clone_detect
unbind part - * clone_remove
unbind sign - * clone_quit
unbind kick - * clone_kick
unbind splt - * clone_remove
unbind rejn - * clone_detect
}
set clone_loaded 1
if {[array exists clonelist]} { unset clonelist }
}
}
global clone_loaded
set clone_loaded 0
clonecheckload
if {$clonecheck} { set clonestatus "on" } { set clonestatus "off" }
putlog "- Clone detection v3.5 \($clonestatus\) by By-Tor, Ernst & Flash."
putlog " Max clones allowed: $maxclone. Banning for $clonebantime mins."
unset clonestatus
thanks a lot
Yoda