Code: Select all
for {set count 0} {$count < [string length $nick]} {incr count} {
 if {![string match -nocase "\[a-z\]" [string index $nick $count]]} {
  break
 }
}
set nick_alphabet [string index $nick 0 $count]
Code: Select all
is:
if {[string match -nocase "\[a-z\]" $var]} {
same as:
if {[string match -nocase {[abcdefghijklmnopqrstuvwxyz]} $var]} {
Code: Select all
if {[regexp -nocase {^([a-z]{3,})[0-9]{2,}$} $nick {} anick] && [lsearch -exact $floodnicks [split $nick]] == -1 } {
	set anick [string tolower $anick]
	lappend floodnicks [list $anick $nick]
	if { [llength [lsearch -exact -all $floodnicks $anick] > 2 } {
		foreach bnick [lsearch -all -inline [string tolower [chanlist $chan]] $anick] {
			newchanban $chan [maskban [getchanhost $bnick $chan]] floodnicks "owned by script for Floodnicks" 1440
		}
	}
}Code: Select all
if {[regexp -nocase {^([a-z]{3,})[0-9]{2,}$} $nick]} {
 for {set count 0} {$count < [string length $nick]} {incr count} {
  if {![string match -nocase {*[a-z]*} [string index $nick $count]] || [string match {*[0-9]*} [string index $nick $count]]} {
   set botnetnick [string range $nick 0 [expr $count -1]]; set index [expr $count -1]; set restnicklength [string length [string range [expr $index +1] end]]; break
   }
 }
 set floodnicks [list]
 foreach user [chanlist $chan] {
  if {[regexp -nocase {^([a-z]{3,})[0-9]{2,}$} $user] && [string equal [string range $botnetnick 0 $index] [string range $user 0 $index]] && [regexp {^[0-9]{$restnicklength,}} $user]} {
   lappend floodnicks $user
   }
 }
 if {[llength $floodnicks] >= 2} {
  putquick "MODE $chan +b $botnetnick*!*@* -next
  foreach bot [split $floodnicks] {
   putquick "MODE $chan +b *!*@[lindex [split [getchanhost $bot $chan] @] 1]" -next
    putquick "KICK $chan $bot :Suspected flood botnet." -next
    }
  }
}
Code: Select all
   if {[llength [lsearch -exact -all $floodnicks $anick]] > 2} {
      foreach bnick [lsearch -all -inline [string tolower [chanlist $chan]] $anick] {
         newchanban $chan [maskban [getchanhost $bnick $chan]] floodnicks "owned by script for Floodnicks" 1440
   } else { unset $floodnicks }
Code: Select all
#
# antifloodbot.tcl by sKy\ - version 1.2
#
# Changelog to verions 1.0: script works now (hopefully :P)
# Changelog to version 1.1: script now smaller, removed unless debugmode
#
# - thanks to Apache, he show me the basic idea of this
# - thanks to #TCL @ irc.quakenet.org - especialy thommey for for the lsearch proc
#
#
# notice, this script need: mytools.tcl version 0.3 or above
#
# suggestions/bugreports/.... pm me @ irc.quakenet.org - #apache-root
#
# usage:
# .chanset #yourchannel +antifloodbot
#
# how long must a nick. if to short = ban
set minlenghnick 1
# in seconds... the time...
set floodbotintime 10
# for example if 3 user with same nicks join
set maxfloodnicks 3
# with same idents
set maxfloodidents 3
# kickmessages
set toshortnickkick "Possible floodbot. Type 1. (to short nick without digits)"
set floodnickkick "Possible floodbot. Type 2. (to much users with same nicknames)"
set floodidentkick "Possible floodbot. Type 3. (to much users with same idents)"
# Do not edit below
setudef flag antifloodbot
bind join - * floodbot:join
proc floodbot:join { nickname hostname handle channel } {
	global minlenghnick toshortnickkick floodbotintime maxfloodnicks floodnickkick
	if { [string match -nocase "*.users.quakenet.org*" $hostname] } { return }
	if { $nickname == $::botnick } { return }
	if {! [channel get $channel antifloodbot] } { return }
	if { [matchattr $handle mnofbvI|mnfovI $channel] } { return }
	set BUZAin "floodbotjoin!$hostname"
	set BUZAout [get:ban:mask $BUZAin]
	set ident [lindex [split $hostname "@"] 0]
	regsub -all {[0-9]*} $nickname "" kurznick
	set lenghtnick [string length $kurznick]
	if { $lenghtnick <= $minlenghnick } {
		put:quick $channel +b $BUZAout
		kick:user $nickname $channel $toshortnickkick
		return
	}
	if { [regexp {[0-9]} $nickname] } { floodbot:nick $nickname $hostname $handle $channel $BUZAout $kurznick }
	if { [regexp {[0-9]} $ident] } { floodbot:ident $nickname $hostname $handle $channel $BUZAout $ident }
}
proc floodbot:nick { nickname hostname handle channel BUZAout kurznick } {
	global zahlenfl minlenghnick toshortnickkick floodbotintime maxfloodnicks floodnickkick
	lappend ::floodnicks($channel,$kurznick) $nickname
	lappend ::floodnickshosts($channel,$kurznick) $BUZAout
	utimer $floodbotintime [list floodbot:uset $channel $kurznick $BUZAout $nickname ]
	set lenghtfloodnicks [llength $::floodnicks($channel,$kurznick)]
	if { $lenghtfloodnicks >= $maxfloodnicks } {
		set zusammfasshost "$kurznick*!*@*"
		put:quick $channel +b $zusammfasshost
		timer 5 [list badall:banremove $zusammfasshost $channel] 
		foreach einzelnickfloodhosts $::floodnickshosts($channel,$kurznick) {
			put:quick $channel +b $einzelnickfloodhosts
		}
		foreach einzelfloodnicks $::floodnicks($channel,$kurznick) {
			kick:user $einzelfloodnicks $channel $floodnickkick
		}
	}
}
proc floodbot:uset { channel kurznick BUZAout nickname } {
	set ::floodnicks($channel,$kurznick) [lremove $::floodnicks($channel,$kurznick) $nickname ]
	set ::floodnickshosts($channel,$kurznick) [lremove $::floodnickshosts($channel,$kurznick) $BUZAout ]
}
proc floodbot:ident { nickname hostname handle channel BUZAout ident } {
	global zahlenfl minlenghnick toshortnickkick floodbotintime maxfloodidents floodnickkick floodidentkick
	regsub -all {[0-9]*} $ident "" kurzident
	lappend ::floodidents($channel,$kurzident) $nickname
	lappend ::floodidenthosts($channel,$kurzident) $BUZAout
	utimer $floodbotintime [list floodbot:uset:ident $channel $kurzident $BUZAout $nickname ]
	set lenghtfloodidents [llength $::floodidents($channel,$kurzident)]
	if { $lenghtfloodidents >= $maxfloodidents } {
		set zusammfasshost "*!$kurzident*@*"
		put:quick $channel +b $zusammfasshost
		timer 5 [list badall:banremove $zusammfasshost $channel] 
		foreach einzelidentfloodhosts $::floodidenthosts($channel,$kurzident) {
			put:quick $channel +b $einzelidentfloodhosts
		}
		foreach einzelfloodidents $::floodidents($channel,$kurzident) {
			kick:user $einzelfloodidents $channel $floodidentkick
		}
	}
}
proc floodbot:uset:ident { channel kurzident BUZAout nickname } {
	set ::floodidents($channel,$kurzident) [lremove $::floodidents($channel,$kurzident) $nickname]
	set ::floodidenthosts($channel,$kurzident) [lremove $::floodidenthosts($channel,$kurzident) $BUZAout]
}
Code: Select all
# mytools.tcl by sky
# version 0.3
# usage:
# put:quick channel what ?target?
#
#
#
# returns - nothing
#
# supports only mode. use this command instand of: putquick "MODE $channel $what" or putquick "MODE $channel $what $target"
# does not support +k $key / -k $key
# or +l $limit
#
# - will not set modes which are allready set / will not unset modes which are set (for op, voice, channelmodes and bans)
set put_quick_refresh 201
set put_quick_againinput 5
proc putquick:op { channel target } {
	global put_quick_againinput
	if {! [info exists ::aoped($channel,$target) ] } {
		set ::aoped($channel,$target) 1
		utimer $put_quick_againinput [list unset ::aoped($channel,$target)]
		if { [onchan $target $channel] } {
			if { ! [isop $target $channel] } {
				put:quick:input $channel +o $target
			}
		}	
	}
}
proc putquick:deop { channel target } {
	global put_quick_againinput
	if {! [info exists ::adeoped($channel,$target) ] } {
		set ::adeoped($channel,$target) 1
		utimer $put_quick_againinput [list unset ::adeoped($channel,$target)]
		if { [onchan $target $channel] } {
			if { [isop $target $channel] } {
				put:quick:input $channel -o $target
			}
		}
	}
}
proc putquick:ban { channel hostname } {
	global put_quick_againinput
	if {! [info exists ::allready_banned($channel,$hostname) ] } {
		set ::allready_banned($channel,$hostname) 1
		utimer $put_quick_againinput [list unset ::allready_banned($channel,$hostname)]
		set resultISBAN [isban:test $hostname $channel]
		if { $resultISBAN == "ISNOTBAN" } {
			put:quick:input $channel +b $hostname
		}
	}
}
# yeah, there is a function ischanban, but i don`t want to use it because the bot sends to often mode $chan +b
proc putquick:unban { channel hostname } {
	global put_quick_againinput
	if {! [info exists ::allready_unbanned($channel,$hostname) ] } {
		set ::allready_unbanned($channel,$hostname) 1
		utimer $put_quick_againinput [list unset ::allready_unbanned($channel,$hostname)]
		set resultISBAN [isban:test $hostname $channel]
		if { $resultISBAN == "ISBAN" } {
			put:quick:input $channel -b $hostname
		}
	}
}
proc putquick:mode { channel what } {
	global put_quick_againinput
	if {! [info exists ::amode($channel,$what) ] } {
		set ::amode($channel,$what) 1
		utimer $put_quick_againinput [list unset ::amode($channel,$what)]
		set plus_or_minus [string index $what 0]
		set modechange [string index $what 1]
		set modes [getchanmode $channel]
		if { $plus_or_minus == "+" } {
			if {! [string match "*$modechange*" $modes] } {
				put:quick:input $channel $what
			}
		}
		if { $plus_or_minus == "-" } {
			if { [string match "*$modechange*" $modes] } {
				put:quick:input $channel $what
			}
		}
	}
}
proc putquick:voice { channel target } {
	global put_quick_againinput
	if {! [info exists ::avoice($channel,$target) ] } {
		set ::avoice($channel,$target) 1
		utimer $put_quick_againinput [list unset ::avoice($channel,$target)]
		if { [onchan $target $channel] } {
			if { ! [isvoice $target $channel] } {
				put:quick:input $channel +v $target
			}
		}
	}
}
proc putquick:devoice { channel target } {
	global put_quick_againinput
	if {! [info exists ::adevoice($channel,$target) ] } {
		set ::adevoice($channel,$target) 1
		utimer $put_quick_againinput [list unset ::adevoice($channel,$target)]
		if { [onchan $target $channel] } {
			if { [isvoice $target $channel] } {
				put:quick:input $channel -v $target
			}
		}
	}
}
proc put:quick { channel what {target ""} } {
	set plus_or_minus [string index $what 0]
	set modechange [string index $what 1]
	if { $plus_or_minus == "+" } {
		if { $modechange == "o" } {
			putquick:op $channel $target
			return
		}
		if { $modechange == "b" } {
			putquick:ban $channel $target
			return
		}
		if { $modechange == "v" } {
			putquick:voice $channel $target
			return
		}
		putquick:mode $channel $what
		return
	}
	if { $plus_or_minus == "-" } {
		if { $modechange == "o" } {
			putquick:deop $channel $target
			return
		}
		if { $modechange == "b" } {
			putquick:unban $channel $target
			return
		}
		if { $modechange == "v" } {
			putquick:devoice $channel $target
			return
		}
		putquick:mode $channel $what
		return
	}
	return
}
proc put:quick:clearqueue { channel } {
	if { [info exists ::put_quick_list($channel) ] } {
		unset ::put_quick_list($channel)
	}
	if { [info exists ::put_quick_list_mode_plus($channel) ] } {
		unset ::put_quick_list_mode_plus($channel) 
	}
	if { [info exists ::put_quick_list_mode_minus($channel) ] } {
		unset ::put_quick_list_mode_minus($channel)
	}
	if { [info exists ::put_quick_list_bans_plus($channel) ] } {
		unset ::put_quick_list_bans_plus($channel)
	}
	if { [info exists ::put_quick_list_bans_minus($channel) ] } {
		unset ::put_quick_list_bans_minus($channel)
	}
	if { [info exists ::put_quick_list_op_plus($channel) ] } {
		set ::put_quick_list_op_plus($channel) ""
	}
	if { [info exists ::put_quick_list_op_minus($channel) ] } {
		set ::put_quick_list_op_minus($channel) ""
	}
	if { [info exists ::put_quick_list_voice_plus($channel) ] } {
		set ::put_quick_list_voice_plus($channel) ""
	}
	if { [info exists ::put_quick_list_voice_minus($channel) ] } {
		set ::put_quick_list_voice_minus($channel) ""
	}
	return
}
proc put:quick:input { channel what {target ""} } {
	if { ! [info exists ::allreadystarted($channel)] } {
		set ::allreadystarted($channel) 1
		after 201 [list put:quick:pushnow $channel]
	}
	if { ! [info exists ::put_quick_list($channel) ] } {
		set ::put_quick_list($channel) ""
	}
	if { ! [info exists ::put_quick_list_mode_plus($channel) ] } {
		set ::put_quick_list_mode_plus($channel) ""
	}
	if { ! [info exists ::put_quick_list_mode_minus($channel) ] } {
		set ::put_quick_list_mode_minus($channel) ""
	}
	if { ! [info exists ::put_quick_list_bans_plus($channel) ] } {
		set ::put_quick_list_bans_plus($channel) ""
	}
	if { ! [info exists ::put_quick_list_bans_minus($channel) ] } {
		set ::put_quick_list_bans_minus($channel) ""
	}
	if { ! [info exists ::put_quick_list_op_plus($channel) ] } {
		set ::put_quick_list_op_plus($channel) ""
	}
	if { ! [info exists ::put_quick_list_op_minus($channel) ] } {
		set ::put_quick_list_op_minus($channel) ""
	}
	if { ! [info exists ::put_quick_list_voice_plus($channel) ] } {
		set ::put_quick_list_voice_plus($channel) ""
	}
	if { ! [info exists ::put_quick_list_voice_minus($channel) ] } {
		set ::put_quick_list_voice_minus($channel) ""
	}
	set plus_or_minus [string index $what 0]
	set modechange [string index $what 1]
	if { $plus_or_minus == "+" || $plus_or_minus == "-" } { 
		if { $plus_or_minus == "+" } {
			if { $modechange == "t" || $modechange == "n" ||
			$modechange == "i" || $modechange == "m" ||
			$modechange == "k" || $modechange == "l" ||
			$modechange == "p" || $modechange == "s" ||
			$modechange == "c" || $modechange == "C" ||
			$modechange == "N" || $modechange == "r" ||
			$modechange == "D" || $modechange == "u" } {
				append ::put_quick_list_mode_plus($channel) $modechange
				return
			}
			if { $modechange == "o" } {
				append ::put_quick_list_op_plus($channel) "$target "
			}
			if { $modechange == "v" } {
				append ::put_quick_list_voice_plus($channel) "$target "
			}
			if { $modechange == "b" } {
				append ::put_quick_list_bans_plus($channel) "$target "
			}
		}
		if { $plus_or_minus == "-" } {
			if { $modechange == "t" || $modechange == "n" ||
			$modechange == "i" || $modechange == "m" ||
			$modechange == "k" || $modechange == "l" ||
			$modechange == "p" || $modechange == "s" ||
			$modechange == "c" || $modechange == "C" ||
			$modechange == "N" || $modechange == "r" ||
			$modechange == "D" || $modechange == "u" } {
				append ::put_quick_list_mode_minus($channel) $modechange
				return
			}
			if { $modechange == "o" } {
				append ::put_quick_list_op_minus($channel) "$target "
			}
			if { $modechange == "v" } {
				append ::put_quick_list_voice_minus($channel) "$target "
			}
			if { $modechange == "b" } {
				append ::put_quick_list_bans_minus($channel) "$target "
			}
		}
		set oplist_lenght_plus [llength $::put_quick_list_op_plus($channel)]
		set oplist_lenght_minus [llength $::put_quick_list_op_minus($channel)]
		set voicelist_lenght_plus [llength $::put_quick_list_voice_plus($channel)]
		set voicelist_lenght_minus [llength $::put_quick_list_voice_minus($channel)]
		set banlist_lenght_plus [llength $::put_quick_list_bans_plus($channel)]
		set banlist_lenght_minus [llength $::put_quick_list_bans_minus($channel)]
		set lenght [expr $banlist_lenght_plus + $banlist_lenght_minus + $oplist_lenght_plus + $oplist_lenght_minus + $voicelist_lenght_plus + $voicelist_lenght_minus]
		if { $lenght == 6 } {
			put:quick:pushnow $channel
		}
	} else {
		return "Error: illegal modechange"
	}
	return
}
proc put:quick:pushnow { channel } {
	global put_quick_refresh botnick
	if { ! [info exists ::put_quick_list($channel) ] } {
		set ::put_quick_list($channel) ""
	}
	if { ! [info exists ::put_quick_list_mode_plus($channel) ] } {
		set ::put_quick_list_mode_plus($channel) ""
	}
	if { ! [info exists ::put_quick_list_mode_minus($channel) ] } {
		set ::put_quick_list_mode_minus($channel) ""
	}
	if { ! [info exists ::put_quick_list_bans_plus($channel) ] } {
		set ::put_quick_list_bans_plus($channel) ""
	}
	if { ! [info exists ::put_quick_list_bans_minus($channel) ] } {
		set ::put_quick_list_bans_minus($channel) ""
	}
	if { ! [info exists ::put_quick_list_op_plus($channel) ] } {
		set ::put_quick_list_op_plus($channel) ""
	}
	if { ! [info exists ::put_quick_list_op_minus($channel) ] } {
		set ::put_quick_list_op_minus($channel) ""
	}
	if { ! [info exists ::put_quick_list_voice_plus($channel) ] } {
		set ::put_quick_list_voice_plus($channel) ""
	}
	if { ! [info exists ::put_quick_list_voice_minus($channel) ] } {
		set ::put_quick_list_voice_minus($channel) ""
	}
	set change_plus "+$::put_quick_list_mode_plus($channel)[string repeat "b" [llength $::put_quick_list_bans_plus($channel)]][string repeat "o" [llength $::put_quick_list_op_plus($channel)]][string repeat "v" [llength $::put_quick_list_voice_plus($channel)]]"
	if { $change_plus == "+" } { set change_plus "" }
	set change_minus "-$::put_quick_list_mode_minus($channel)[string repeat "b" [llength $::put_quick_list_bans_minus($channel)]][string repeat "o" [llength $::put_quick_list_op_minus($channel)]][string repeat "v" [llength $::put_quick_list_voice_minus($channel)]]"
	if { $change_minus == "-" } { set change_minus "" }
	set change "$change_minus$change_plus $::put_quick_list_bans_minus($channel)$::put_quick_list_op_minus($channel)$::put_quick_list_voice_minus($channel)$::put_quick_list_bans_plus($channel)$::put_quick_list_op_plus($channel)$::put_quick_list_voice_plus($channel)"
	set x [string map {" " ""} $change]
	if { $x != "" } {
		putlog "put:quick:pushnow - putquick MODE $channel $change"
		if { [isop $botnick $channel] } {
			putquick "MODE $channel $change" -next
		}
		put:quick:clearqueue $channel
		after $put_quick_refresh [list put:quick:pushnow $channel]
		return
	}
	after $put_quick_refresh [list put:quick:pushnow $channel]
	return
}
###################################################################################################################################
#					isban:test													#
###################################################################################################################################
# isban:test $banmask $channel
# old proc, should ne be needed :P
# but unsure
proc isban:test { ISBANin channel } {
	foreach bans [chanbans $channel] { 
		set mask [lindex $bans 0] 
		if {[string match -nocase $ISBANin $mask]} { 
			return "ISBAN"
		 } 
	}
	return "ISNOTBAN"
}
###################################################################################################################################
#			stupid procs															#
###################################################################################################################################
setudef flag bans_with_Q
proc push:mode { channel what {target ""} } {
	if { $what == "-b" } { push:mode:minus:ban $channel $what $target }
	if { $what == "+b" } { push:mode:plus:ban $channel $what $target }
	put:quick $channel $what $target
}
proc push:mode:minus:ban { channel what target } {
	if { ! [channel get $channel bans_with_Q] } {
		pushmode $channel $what $target
		return "push:mode channel not in flag bans_with_Q mode"
	}
	set servicebot [channel get $channel servicebot]
	if { $servicebot != "Q" } {
		pushmode $channel $what $target
		return "push:mode Q not on channel."
	}
	set result [isban:test $target $channel]
	if { $result == "ISBAN" } {
		if { [info exists ::pushmodeminusban($channel,$target) ] } {
			return "push:mode:minus:ban ::pushmodeminusban($channel,$target) info exists ,floodprotected"
		}
		if {! [info exists ::pushmodeminusban($channel,$target) ] } {
			putquick "PRIVMSG Q :bandel $channel $target" -next
			putlog "push:mode:minus:ban PRIVMSG Q :bandel $channel $target"
			set ::pushmodeminusban($channel,$target) 1
			utimer 5 [list unset ::pushmodeminusban($channel,$target) ]
		}
	}
}
proc push:mode:plus:ban { channel what target } {
	if { ! [channel get $channel bans_with_Q] } {
		pushmode $channel $what $target
		return "push:mode channel not in flag bans_with_Q mode"
	}
	set servicebot [channel get $channel servicebot]
	if { $servicebot != "Q" } {
		pushmode $channel $what $target
		return "push:mode Q not on channel."
	}
	set result [isban:test $target $channel]
	if { $result == "ISNOTBAN" } {
		if { [info exists ::pushmodeplusban($channel,$target) ] } {
			return "push:mode:minus:ban ::pushmodeplusban($channel,$target) info exists ,floodprotected"
		}
		if {! [info exists ::pushmodeplusban($channel,$target) ] } {
			putquick "PRIVMSG Q :ban $channel $target" -next
			putlog "push:mode:plus:ban PRIVMSG Q :ban $channel $target"
			set ::pushmodeplusban($channel,$target) 1
			utimer 5 [list unset ::pushmodeplusban($channel,$target) ]
		}
	}
}
###################################################################################################################################
#					maskhostx													#
###################################################################################################################################
# by egghelp.org, autor, i forgot :p
#0: *!user@full.host.tld 
#1: *!*user@full.host.tld 
#2: *!*@full.host.tld 
#3: *!*user@*.host.tld 
#4: *!*@*.host.tld 
#5: nick!user@full.host.tld 
#6: nick!*user@full.host.tld 
#7: nick!*@full.host.tld 
#8: nick!*user@*.host.tld 
#9: nick!*@*.host.tld
# Setting: 
set maskhostDefaultType 1
# The proc: 
proc maskhostxx [list name [list type $maskhostDefaultType]] { 
   if {[scan $name {%[^!]!%[^@]@%s} nick user host]!=3} { 
      error "Usage: maskhost <nick!user@host> \[type\]" 
   } 
   if [string match {[3489]} $type] { 
      if [string match {*[0-9]} $host] { 
         set host [join [lrange [split $host .] 0 2] .].* 
      } elseif {[string match *.*.* $host]} { 
         set host *.[join [lrange [split $host .] end-1 end] .] 
      } 
   } 
   if [string match {[1368]} $type] { 
      set user *[string trimleft $user ~] 
   } elseif {[string match {[2479]} $type]} { 
      set user * 
   } 
   if [string match {[01234]} $type] { 
      set nick * 
   } 
   set name $nick!$user@$host 
}
###################################################################################################################################
#					banned user join												#
###################################################################################################################################
bind nick - * banned:user:nickchange
proc banned:user:nickchange { nickname hostname handle channel newnick } {
	set nickname $newnick
	banned:user:join $nickname $hostname $handle $channel
}
bind join - * banned:user:join
proc banned:user:join { nickname hostname handle channel } {
	set hostname "$nickname!$hostname"
	set banmask ""
	foreach ban [banlist $channel] {
		set host [lindex [split $ban] 0]
		if { [string match -nocase $host $hostname] } {
			set banmask $host
		}
		if { $banmask != "" } {
			banned:user:getout $nickname $hostname $handle $channel $banmask
			return "banned:user:join channel banned match found"
		}
	}
	foreach ban [banlist] {
		set host [lindex [split $ban] 0]
		if { [string match -nocase $host $hostname] } {
			set banmask $host
		}
		if { $banmask != "" } {
			banned:user:getout $nickname $hostname $handle $channel $banmask
			return "banned:user:join global banned match found"
		}
	}
	return "banned:user:join no match found"
}
proc banned:user:getout { nickname hostname handle channel banmask } {
	flood:detect $channel
	put:quick $channel +b $banmask
	putlog "banned:user:getout pushmode $channel +b $banmask"
}
###################################################################################################################################
#					get:ban:mask													#
###################################################################################################################################
# ussage: get:ban:mask nick!user@host $channel
# return: better hostmask
set dynhosts {
		*.users.quakenet.org
		*@*proxad*
		*@*chello*
		*@*kabelbw*
		*@*mediaways*
		*@*arcor*
		*@*ipconnect*
		*@*arcor*
		*@*ipconnect*
		*@*dsl*
		*@*wanadoo*
		*@*dial*in*
		*@*.aol.*
		*@*.telia.co*
		*@*rev.gaoland.ne*
		*@*access.telenet.b*
		*@*noos.f*
		*@*tvcablenet.b*
		*@*tiscali.f*
		*@*.comcast.ne*
		*@*dsl-verizon.ne*
		*@*charter-stl.co*
		*@*optonline.ne*
		*@*mindspring.co*
		*@*attbi.co*
		*@*btcentralplus.co*
		*@*netvision.net.il
		*@*charter.co*
		*@*optonline.ne*
		*@*rcn.co*
		*@*bezeqint.ne*
		*@*primacom.ne*
		*@*numericable.f*
		*@*cust.tele2.f*
		*@*.ikexpress.com
		*@*.attbi.com
		*@*.charter.com
		*@*.cableone.net
		*@*.dsl-verizon.net
		*@*.rr.com
		*@*.att.net
		*@*.insightBB.com
		*@*.pacbell.net
		*@*.nf.net
		*@*.knology.net
		*@*.charter*.net
		*@*.tde.net
		*@*.piekary.net
		*@*.Level?.net
		*@*.telia.com
		*@*.quickclic.net
		*@*.ewetel.net
		*@*.rogers.com
		*@*.ntl.com
		*@*.verizon.net
		*@*.bezeqint.net
		*@*.optonline.net
		*@*.rima-tde.net
		*@*.qualitynet.net
		*@*.cox.net
		*@*.bacs-net.hu
		*@*.club-internet.fr
		*@*.online.no
		*@*.bredbandsbolaget.se
		*@*.auna.net
		*@*.quicknet.nl
		*@*.visit.se
		*@*.bostream.se
		*@*.evc.net
		*@*.blueyonder.co.uk
		*@*.ngi.it
		*@*.e-vei.no
		*@*.d.pppool.de
		*@*.dsl.inet.fi
}
set wronghosts {
		"#!"
		"#!#!
		"#!@#"
		"#!#@#"
		"#!#@"
		"#@#"
		"*!@"
		"#!#@"
}
# script for setting up a optimal banmask
proc get:ban:mask { BUZAin } {
	global BUZAout botnick botname lastbind wronghosts dynhosts
       set BUZAin [string map {~ ""} $BUZAin]
       set BUZA [lindex [split $BUZAin "!"] 1]
       set ::BUZAout "*!*$BUZA"
	set DYNHOST "1"
	if {[string match -nocase "*.users.quakenet.org*" $BUZAin]} { set BUZA [lindex [split $BUZAin "@"] 1] ; set ::BUZAout "*!*@$BUZA" ; set NHOST "1" }
	foreach xy $dynhosts {
		if {[string match -nocase $xy $BUZAin]} { set BUZA [lindex [split $BUZAin "@"] 1] ; set ::BUZAout "*!*@$BUZA" ; set DYNHOST "un" }
	}
	set xxxx [string map {* #} $BUZAout]
	if { "#!" == $xxxx } { set ::BUZAout "error!*@*" ; putlog "proc get:ban:mask in: $BUZAin out: $BUZAout - *!*@* - lastbind: $lastbind " }
	if { "#!#" == $xxxx } { set ::BUZAout "error!*@*" ; putlog "proc get:ban:mask in: $BUZAin out: $BUZAout - *!*@* - lastbind: $lastbind " }
	if { "#!@#" == $xxxx } { set ::BUZAout "error!*@*" ; putlog "proc get:ban:mask in: $BUZAin out: $BUZAout - *!*@* - lastbind: $lastbind" }
	if { "#!#@*" == $xxxx } { set ::BUZAout "error!*@*" ; putlog "proc get:ban:mask in: $BUZAin out: $BUZAout - *!*@* - lastbind: $lastbind" }
	if { "#!#@" == $xxxx } { set ::BUZAout "error!*@*" ; putlog "proc get:ban:mask in: $BUZAin out: $BUZAout - *!*@* - lastbind: $lastbind" }
	if { "!#@#" == $xxxx } { set ::BUZAout "error!*@*" ; putlog "proc get:ban:mask in: $BUZAin out: $BUZAout - *!*@* - lastbind: $lastbind" }
	if { "#!@" == $xxxx } { set ::BUZAout "error!*@*" ; putlog "proc get:ban:mask in: $BUZAin out: $BUZAout - *!*@* - lastbind: $lastbind" }
	if { [string match -nocase $botnick $BUZAout] } { set BUZAout "error!*@*" ; putlog "proc get:ban:mask in: $BUZAin out: $BUZAout - botnick - lastbind: $lastbind " }
	if { [string match -nocase $botname $BUZAout] } { set BUZAout "error!*@*" ; putlog "proc get:ban:mask in: $BUZAin out: $BUZAout - botname - lastbind: $öastbind " }
	if { $wronghosts == $BUZAout } { set ::BUZAout "error!*@*" ; putlog "proc get:ban:mask in: $BUZAin out: $BUZAout - *!*@* - lastbind: $lastbind " }
       return $BUZAout
}
###################################################################################################################################
#					match:bans													#
###################################################################################################################################
# match:bans $channel
# returns a list with all matching botbans
proc match:bans { channel } {
	set matchlist ""
	foreach bans [chanbans $channel] { 
		set mask [lindex $bans 0] 
		set from [lindex $bans 1] 
		set since [lindex $bans 2]
		set x [string match -nocase $mask $::botname]
		if { $x == 1 } { append matchlist "$mask " }
	}
	return $matchlist
}
###################################################################################################################################
#					kick:user													#
###################################################################################################################################
set kick_floodprot 5
proc kick:user { nickname channel kickmsg } {
	global kick_floodprot
	if { [info exists ::allready_kicked($channel,$nickname) ] } {
		return "kick:user floodprotected"
	}
	if { ! [info exists ::allready_kicked($channel,$nickname) ] } {
		set ::allready_kicked($channel,$nickname) 1
		utimer $kick_floodprot [list unset ::allready_kicked($channel,$nickname) ]
	}
	append ::kick_list($channel) " {$nickname} "
	append ::kick_list_reason($channel) " {$kickmsg} "
	if { ! [info exists ::allready_called_kicksend($channel) ] } {
		set ::allready_called_kicksend($channel) 1
		kick:user:send $channel
	}
}
proc kick:user:send { channel } {
	set que [queuesize]
	set nickname [lindex $::kick_list($channel) 0]
	set reason [lindex $::kick_list_reason($channel) 0]
	set n [string map {" " ""} $nickname]
	if { $n != "" } {
		if {! [onchan $nickname $channel] } {
			set ::kick_list($channel) [lreplace $::kick_list($channel) 0 0]
			set ::kick_list_reason($channel) [lreplace $::kick_list_reason($channel) 0 0]
			kick:user:send $channel
			return
		}
	}
	if { $que <= 1 } {
		set ::kick_list($channel) [lreplace $::kick_list($channel) 0 0]
		set ::kick_list_reason($channel) [lreplace $::kick_list_reason($channel) 0 0]
		if { [isop $::botnick $channel] } {
			if { [onchan $nickname $channel] } {
				set x [putkick $channel $nickname $reason]
			}
		}
	}
	utimer 2 [list kick:user:send $channel]
}
###################################################################################################################################
#					newchan:ban													#
###################################################################################################################################
proc newchan:ban { channel BUZAout creator comment lifetime } {
	if { [info exists ::newwchanban($BUZAout,$channel) ] } {
		return "newchan:ban - floodprotedted"
	}
	if {! [info exists ::newwchanban($BUZAout,$channel) ] } {
		set ::newwchanban($BUZAout,$channel) 1
		utimer 5 [list unset ::newwchanban($BUZAout,$channel)]
	}
	if { [string match -nocase "*.users.quakenet.org*" $BUZAout] } { 
		set lifetime 0
	}
	newchanban $channel $BUZAout $creator $comment $lifetime
}
###################################################################################################################################
#					new:ban													#
###################################################################################################################################
# new:ban "$BUZAout" "$creator" "$comment" "$lifetime"
proc new:ban { BUZAout creator comment lifetime } {
	global botnick botname lastbind
	if { $BUZAout == "" } { putlog "proc new;ban - error 1 - BUZAout empty - $lastbind" ; return 1 }
	if { $creator == "" } { putlog "proc new;ban - error 2 - BUZAout empty - $lastbind" ; return 1 }
	if { $comment == "" } { putlog "proc new;ban - error 3 - BUZAout empty - $lastbind" ; return 1 }
	if { $lifetime == "" } { putlog "proc new;ban - error 4 - BUZAout empty - $lastbind" ; return 1 }
	if { [info exists ::newwban($BUZAout) ] } {
		return 1
	}
	if {! [info exists ::newwban($BUZAout) ] } {
		set ::newwban($BUZAout) 1
		timer 1 [list unset ::newwban($BUZAout)]
	}
	if { [string match -nocase "*.users.quakenet.org*" $BUZAout] } { 
		set lifetime 0
		set host [lindex [split $BUZAout "@"] 1]
		set authname [lindex [split $host "."] 0]
		set file "authglobalban.txt" 
		set wfile [open $file "a"] 
		puts $wfile $authname
		close $wfile
	 }
	newban $BUZAout $creator $comment $lifetime
}
###################################################################################################################################
#					flood detect													#
###################################################################################################################################
set floods 10
set fsecs 30
proc flood:detect { channel } {
	global floods fsecs botnick
	if {! [isop $botnick $channel] } { return 0 }
	if {! [info exists ::fdmerk($channel) ] } {
		set ::fdmerk($channel) 0
	}
	set ::fdmerk($channel) [expr $::fdmerk($channel) +1]
	utimer $fsecs [list flood:detect:minus "$channel"]
	if { $::fdmerk($channel) >= $floods } {
		flood:detect:detected "$channel"
	}
}
proc flood:detect:detected { channel } {
	if {! [info exists ::adetected($channel) ] } {
		set ::adetected($channel) 1
		timer 2 [list flood:detect:minus:a "$channel"]
		if {! [info exists ::adetectedbc($channel) ] } {
			set ::adetectedbc($channel) 1
			timer 2 [list unset ::adetectedbc($channel) ]
			set modes "[getchanmode $channel]"
			putlog "flood detected in $channel."
			timer 1 [list flood:detect:minus:m "$channel"]
			timer 2 [list flood:detect:minus:r "$channel"]
			utimer 2 [list putquick "PRIVMSG $channel :A flood in $channel has been detected. +mr is set untill all flooders are removed."]
			if {! [string match "*m*" $modes] } { put:quick $channel +m }
			if {! [string match "*r*" $modes] } { put:quick $channel +r }
		}
	}
}
proc flood:detect:minus { channel } {
	if { [info exists ::fdmerk($channel) ] } {
		set ::fdmerk($channel) [expr $::fdmerk($channel) -1]
	}
}
proc flood:detect:minus:a { channel } {
	if { [info exists ::adetected($channel) ] } {
		unset ::adetected($channel)
	}
}
proc flood:detect:minus:m { channel } {
	global botnick
	set modes "[getchanmode $channel]"
	if {! [isop $botnick $channel] } { return 0 }
	if { [string match "*m*" $modes] } { pushmode $channel -m }
}
proc flood:detect:minus:r { channel } {
	global botnick
	set modes "[getchanmode $channel]"
	if {! [isop $botnick $channel] } { return 0 }
	if { [string match "*r*" $modes] } { pushmode $channel -r }
}
###################################################################################################################################
#					lsearch													#
###################################################################################################################################
# proc sponserd by thommey
proc lremove { list what } {
	while { [set pos [lsearch -exact $list $what]] != -1 } {
			set list [lreplace $list $pos $pos]
		}
	return $list
}
# lremove $::list x
# end of: proc sponserd by thommey
###################################################################################################################################
#					manuel:banremove												#
###################################################################################################################################
proc manuel:banremove { nickname hostname handle channel mode victim } {
	global botnick
	if { $nickname == $botnick } { return 0 }
	if { $nickname == $::server } { return 0 }
	if { $nickname == ""} { return 0 }
	if { $nickname == "Q"} { return 0 }
	if { $nickname == "L"} { return 0 }
	if { $victim == "L"} { return 0 }	
	if { $victim == "Q"} { return 0 }
	if { [matchattr $handle b|- $channel] } { return 0 }
	if {! [matchattr $handle bnmfo|nmfo $channel] } { return 0 }
		foreach bans [banlist $channel] {
			set hostm "[lindex $bans 0]"
			set reason "[lindex $bans 1]"
			set warnsub "The hostmask: $hostm is in my internal banlist from $channel (reason: $reason). If you want to remove it type \$unban $hostm . If you just want to cleanup the banlist type please \$ub and do not clean up the banlist `by hand`."
		if { [string match -nocase $hostm $victim] } { puthelp "NOTICE $nickname :$warnsub" }
	}	
	foreach bansg [banlist] {
		set hostmg "[lindex $bansg 0]"
		set reasong "[lindex $bansg 1]"
		set warnsubg "The hostmask: $hostmg is in my global banlist (reason: $reasong). Only global owners can remove this ban with \$gban delete $hostmg . If you just want to cleanup the banlist type please \$ub and do not clean up the banlist `by hand`."
		if { [string match -nocase $hostmg $victim] } { puthelp "NOTICE $nickname :$warnsubg" }
	}
}
###################################################################################################################################
#					banremove													#
###################################################################################################################################
proc badall:banremove { BUZAout channel } {
	set y "[isban $BUZAout]"
	if { $y == "1" } { return 0 }
	set x [isban $BUZAout $channel]
	if { $x == "1" } { return 0 }
	if { [info exists ::nobanremove($channel,$BUZAout) ] } {
		if {[string match -nocase "$::nobanremove($channel,$BUZAout)" $BUZAout]} { return 0 }
	}
	put:quick $channel -b $BUZAout
}