This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

antitrojan.tcl by me :)

Support & discussion of released scripts, and announcements of new releases.
User avatar
sKy
Op
Posts: 194
Joined: Thu Apr 14, 2005 5:58 pm
Location: Germany

antitrojan.tcl by me :)

Post by sKy »

Is currently a testversion, i want your feedback about the detection and as well about the code.

If you have a suggestion let me know.
To run this script you need mytools.tcl, i wll create a new post for better overview.

Code: Select all


###################################################################################################################################
#						antitrojan.tcl infos											#
###################################################################################################################################

# -+--+--+--+--+--+
# copyright:
# -+--+--+--+--+--+

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

# antitrojan.tcl version 0.1 - by sKy\ - #Apache-root @ irc.quakenet.org
# Remember removing copyright is lame...

# this script is based on: (proc trojan:meltdown)
#################################################################
# Meltdowns NickChecker V0.1 (25-09-2004)				  #
# Contact: meltdown@gmx.at | #meltdown on quakenet              #
# http://scripts.udp.at                                         #
# [! LEAVE THESE CREDITS INTACT. !] thx...                      #
#################################################################
# without his great code i got no idea "how to detect random"
# thanks :)

# -+--+--+--+--+--+
# end copyright:
# -+--+--+--+--+--+

# Read this infos, else the script won`t work. :p
# If you are not able to read this little doc
# i will not help you.

# does a /whois 1 $nickname on every user which joins your channel
# if something seems like a spam bot some score will be added
# rather, if score is to high the user will be banned on each channel the script is active
# script has a floodprotection which means join/part flood won`t hurt.
# people which are allready in the global or channel banlist will not been whoised.

# !!!
# this scripts need mytools.tcl version 0.6 or above !
# without mytools.tcl the bot will only spamm your partylne with errors (load it before loading this script.)
# get it at forum www.egghelp.org (own website comming soon)
# !!!

# add to your config
# source scripts/antitrojan.tcl
# rehash your bot, script should work

# .chanset #yourchannel +antitrojan	<- turn on
# .chanset #yourchannel -antitrojan	<- turn off

# script is currenty a beta version, which means there can be some bugs inside
# If something goes wrong, do not bother me!
# But if you found bugs or have any usefull suggestions please tell me.
# I need your feedback.
# To contact me write a private message to me on irc or write an pm
# to me on www.egghelp.org userforum

# script has a debug mode... you can turn off kick/bans and you see everything on paryline via putlogs
# might be useful if you want first configure the script and look which one will be kicked in the furtre if you turn on kickfuntion

# people which are banned can unban hisself with:
# /msg botnick removeme
# them will be added to a user called nofloodbot

# .+host nofloodbot *!*@whatever.org on that way you can extempt users by hand too
# error rate should be less then 2-5%

# the script does not listen for private spam to the bot (via privmsg/notice/...)
# get another script therefore

# Sure you can edit the source to your own needs, but if something goes wrong don`t ask me.
# Please do not modify the script and say you have done a "better" version.
# If you want a to create a better version make your own one!

# At least, i hope you think this script is useful.
# Have fun and enjoy.

###################################################################################################################################
#						antitrojan.tcl configuration											#
###################################################################################################################################

###############
# - Detection
###############

# any of the channels the bot is on, must be valid
set trojan_testchan "#Apache-root"

# if the nickname + ident consits only big letters this score will be added
set trojan_only_big 10

# if more then .. digits inside the nick
set digits_in_nickname 4

# or more then .. digtis in ident
set digits_in_ident 4

# then this points will be added
set trojan_digit_nickname 10

# then this points will be added
set trojan_digit_ident 10

# if realname is random then this points will be added
set trojan_random_realname 30

# if realname filed with color then this points will be added(not often used on quakenet)
set trojan_realname_with_color 0

# all colors (for realname/away check)
set trojan_colors "   "

# all badwords (for realname/away check)
set trojan_badwords "# www decode http"

# if authname is random then this points will be added (not often used on quakenet)
set trojan_random_authname 0

# if badword inside away msg (not often used on quakenet)
set trojan_away_with_badword 0

# if a badword is inside the realname (not often used on quakenet)
set trojan_realname_with_badword 0

# if away msg is random text (not often used on quakenet)
set trojan_random_away 0

# if away msg is colored (not often used on quakenet)
set trojan_away_with_color 0

# the time the user should idle
set trojan_idletime 30

# if less them that time then this points will be added
set trojan_less_idle 0

# if trojan has this status in any channel points will be decrased
set trojan_status_op 3
set trojan_status_voice 2
set trojan_status_regular 2
set trojan_status_delayed 2

# if user is in less then chans:
set trojan_minimum_chans 4

# score + this points if to less chans
set trojan_to_less_chans 10

# if nick consits this it will not be a trojan (user extempt), you can set to "" too.
set trojan_goodwords "bnc off et cs play game zzz"

# if nickname is random
set trojan_random_nickname 30

# if ident is random
set trojan_random_ident 20

#############################
# - Remove from trojan list
#############################

# comment this line with a # at start if you don`t want people able to remove hisself from banlist
# for sure it will not remove people which are banned with other reason... don`t unbind if you don`t like unless privmsgs :)
bind msg - removeme trojan:msg:removeme

######################
# - Kick/Ban options
######################

# kickmsg:
# trojanbot <- this word is important. if a user /msg botnick removeme - then the bot will remove matching global or channel bans if this word is inside the kickreason
# which means, let this word inside the kickmsg... you can change it, but then change it in the code below to
# search for #1 and #2 markes if you want change it. if you don`t know, just let this word inside the kickmsg
# variables are :id: :points: :botnick:
# if you want to use { } / \ [ ] $ " inside the kickmsg, you have to escape them which means you have to write
# not only ] --> \] ....
set trojan_kick_reason "1..:: Reason: detected as trojanbot :: If you arn`t floodbot, you can rejoin. :: And please type: /msg :botnick: removeme 1 :: badpoints: :points: :: ID: :id: ::.."

# maximum badpoints, if more -> ban
set trojan_max_points 11

# ban trojan? 1 yes, 0 no
# ban will not expire, op`s can remove them. be ensure that you use a scripts which controll the banlistlenght
set trojan_ban 1

# kick trojan? 1 yes, 0 no
set trojan_kick 1

# use newchanban? useful to get clones off the spammbot outside too.
set trojan_newchanban 0

# the bantime if you use newchanban, something between 1 - 1440 will be useful
# 1440 min = 1 day and those bots change mosttimes ip after 1 day
set trojan_newchan_bantime 10

# use global bans? 0 no, 1 yes. 0 suggested
set trojan_newban 0

# global bantime in min
set trojan_newban_bantime 1

###################
# - Debug options
###################

# show on partyline who will be banned or kicked? 1 yes, 0 no
set trojan_debugmode 1

# show many putlogs for debuging...
set ::trojan_debug_mode 1

# how long a user is stored as authed
set authed_time 60

# how long a user is stored as away
set away_time 60

# in minutes how long a nick is a ircop
set ircop_time 1400

# minutes before the bot will do a whois again
# join/part floods won`t hurt if you don`t decrase
set trojan_floodprot 5

###################################################################################################################################
#						less channels	(alpha)										#
###################################################################################################################################

# .chanset #yourchannel +less_channels
# .chanset #yourchannel -less_channels
# .chanset #yourchannel min_channel 5
# or whatever

set to_less_channels_reason "You are in to less channels."

setudef flag less_channels

setudef str min_channels

proc lesschannel { nickname count_chans } {
	global botnick to_less_channels_reason
	set botnic [string tolower $botnick]
	set nickname [string tolower $nickname]
	if { $nickname == $botnic } { return }
	foreach channel [channels] {
		if { ! [validchan $channel] } { continue }
		if { ! [isop $botnick $channel] } { continue }
		if { ! [channel get $channel less_channels] } { continue }
		if { [onchan $nickname $channel] } { continue }
		set host [getchanhost $nickname]
		set BUZAin "trojankeepout!$host"
		set hostname [get:ban:mask $BUZAin]
		if { [string match -nocase "*.users.quakenet.org*" $hostname] } { continue }
		set fullhost "$nickname!$hostname"
		set handle [finduser $fullhost]
		if { [matchattr handle mnofvI|mnofvI $channel] } { continue }
		if { [string equal -nocase $handle "nofloodbot"] } { return }
		set min_channels [channel get $channel min_channels]
		if { $min_channels == "" } {
			continue
		}
		if { $min_channels == 1 } {
			continue
		}		
		if { $min_channels == 2 } {
			continue
		}
		if { $min_channels < $count_chans } { return }
		put:quick $channel +b $hostname
		kick:user $channel $nickname $to_less_channels_reason
		flood:detect $channel
	}
}

###################################################################################################################################
#						trojan bind nick											#
###################################################################################################################################

# bind nick - * trojan:nickchange
proc trojan:nickchange { nickname hostname handle channel newnick } {
	if { ! [validchan $channel] } { return }
	global botnick
	if { $nickname == $botnick } { return }
	if { $newnick == $botnick } { return }
	set nickname $newnick
	trojan:join $nickname $hostname $handle $channel
}

###################################################################################################################################
#						trojan test join											#
###################################################################################################################################

proc trojan:test { nickname } {
	global trojan_testchan
	set hostname "x@y"
	set handle "*"
	trojan:join $nickname $hostname $handle $trojan_testchan
}

###################################################################################################################################
#						trojan join												#
###################################################################################################################################

setudef flag antitrojan

# bind join - * trojan:join
proc trojan:join { nickname hostname handle channel } {

	if { ! [channel get $channel antitrojan] } { return }
	global botnick 

	set botnic [string tolower $botnick]
	set nickname [string tolower $nickname]
	if { $nickname == $botnic } { return }

	set nickname [string tolower $nickname]

	global trojan_random_nickname trojan_random_ident trojan_goodwords trojan_floodprot

	if { [matchattr handle mnofvI|mnofvI $channel] } { return }

	if { ! [validchan $channel] } { return }

	if { [string equal -nocase $handle "nofloodbot"] } {
		if { $::trojan_debug_mode } {
			putlog "trojan:join: $nickname -- $hostname -- $channel -- nofloodbot"
		}
		return
	}

	if { [string match -nocase "*.users.quakenet.org*" $hostname] } { return }

	if { [isban $hostname $channel] } { return }
	if { [isban $hostname] } { return }

	if { $trojan_goodwords != "" } {
		foreach nobadword $trojan_goodwords {
			if { [string match -nocase $nobadword $nickname] } {
				return
			}
		}
	}

	set ident [lindex [split $hostname "@"] 0]

	set BUZAout $hostname

	if { [info exists ::trojandns($BUZAout) ] } { return }
	if { ! [info exists ::trojandns($BUZAout) ] } {
		set ::trojandns($BUZAout) 1
		timer $trojan_floodprot [list unset ::trojandns($BUZAout)]
	}

	if { [info exists ::trojan_points($nickname) ] } {
		unset ::trojan_points($nickname)
	}
	set ::trojan_points($nickname) 0

	if { $::trojan_debug_mode } {
		putlog "trojan:join: $nickname -- $hostname -- $channel"
	}

	if { [trojan:meltdown $nickname] } {
		if { $::trojan_debug_mode } {
			putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_random_nickname $trojan_random_nickname"
		}
		set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_random_nickname}]
	}
	if { [trojan:meltdown $ident] } {
		if { $::trojan_debug_mode } {
			putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_random_ident $trojan_random_ident"
		}
		set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_random_ident}]
	}

	global trojan_only_big
	if { [trojan:onlybig $nickname] && [trojan:onlybig $ident] } {
		if { $::trojan_debug_mode } {
			putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_only_big $trojan_only_big"
		}
		set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_only_big}]
	}

	set digit_nickname [trojan:digits $nickname]
	set digit_ident [trojan:digits $ident]

	global digits_in_nickname digits_in_ident trojan_digit_nickname trojan_digit_ident

	if { $digit_nickname >= $digits_in_nickname } {
		if { $::trojan_debug_mode } {
			putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_digit_nickname $trojan_digit_nickname"
		}
		set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_digit_nickname}]
	}

	if { $digit_ident >= $digits_in_ident } {
		if { $::trojan_debug_mode } {
			putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_digit_ident $trojan_digit_ident"
		}
		set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_digit_ident}]
	}

	whois $nickname $hostname $channel

}

###################################################################################################################################
#						meltdowns nickchecker (copy right in script header)						#
###################################################################################################################################

proc trojan:meltdown { input } {
	set result 0
	set check(cons) "bcdfghjklmnpqrstvxyz"
	set check(good) "tt ll ss"
	set check(affixture) "off bnc \[ \] afk"
	set const_count 0
	set score 0
	set txt [string map "0 o 1 l 3 e 7 t 4 a" $input]
	foreach x [split $check(good)] {
		set txt [string map -nocase "$x \"\"" $txt]
	}
	foreach x [split $check(affixture)] {
		if { [string match -nocase *$x* $txt] } {
			set txt [string map -nocase "$x \"\"" $txt]
			set score [expr {$score - 10}]
		}
	}
	for { set x 0 } { $x < [string length $txt] } { incr x } {
		if { [string last [string index $txt $x] $check(cons) ] > -1 } {
			incr const_count
			if { $const_count >= 3 } { set score [expr {$score+10}] }
		} else {
			set const_count 0
		}
	}
	if { $score >= 30 } { 
		set result 1
	}
	return $result
}

###################################################################################################################################
#						trojan onlybig											#
###################################################################################################################################

proc trojan:onlybig { input } {
	set output 0
	set output [regexp {^[A-Z]+$} $input]
	return $output
}

###################################################################################################################################
#						trojan digits												#
###################################################################################################################################

proc trojan:digits { input } {
	set output [regexp -all {[0-9]} $input]
	return $output
}

###################################################################################################################################
#						trojan raw 301 - realname										#
###################################################################################################################################

bind raw - 311 trojan:raw:311

proc trojan:raw:311 { from key text } {
	global trojan_random_realname trojan_colors trojan_badwords trojan_realname_with_badword trojan_realname_with_color
	set nickname [lindex [split $text " "] 1]
	set realname [lindex [split $text ":"] end]
	set nickname [string tolower $nickname]
	global botnick
	set botnic [string tolower $botnick]
	if { $nickname == $botnic } { return }
	if { ! [info exists ::trojan_points($nickname) ] } {
		set ::trojan_points($nickname) 0
	}
	if { [trojan:meltdown $realname] } {
		if { $::trojan_debug_mode } {
			putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_random_realname $trojan_random_realname"
		}
		set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_random_realname}]
	}
	foreach color $trojan_colors {
		if { [string match "*$color*" $realname] } {
#		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_realname_with_color $trojan_realname_with_color"
			set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_realname_with_color}]
			break
		}
	}
	foreach badword $trojan_badwords {
		if { [string match "*$badword*" $realname] } {
#		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_realname_with_badword $trojan_realname_with_badword"
			set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_realname_with_badword}]
			break
		}
	}
	set ::real_name($nickname) $realname
}

###################################################################################################################################
#						realname												#
###################################################################################################################################

proc realname { nickname } {
	if { [info exists ::real_name($nickname) ] } {
		return $::real_name($nickname)
	} else {
		return 0
	}
}

###################################################################################################################################
#						trojan raw 330 - auth										#
###################################################################################################################################

bind raw - 330 trojan:raw:330

proc trojan:raw:330 { from key text } {
	global trojan_random_authname authed_time
	set nickname [lindex [split $text " "] 1]
	set authname [lindex [split $text " "] 2]
#	putlog "trojan: nickname: $nickname -- authname: $authname "
	set nickname [string tolower $nickname]
	global botnick
	set botnic [string tolower $botnick]
	if { $nickname == $botnic } { return }
	if { ! [info exists ::trojan_points($nickname) ] } {
		set ::trojan_points($nickname) 0
	}
	if { [trojan:meltdown $authname] } {
#		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_random_authname $trojan_random_authname"
		set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_random_authname}]
	}
	set ::authed($nickname) $authname
	utimer $authed_time [list catch { unset ::authed($nickname) } error]
}

###################################################################################################################################
#						is authed or not											#
###################################################################################################################################

proc authed { nickname } {
	if { [info exists ::authed($nickname) ] } {
		return 1
	} else {
		return 0
	}
}

###################################################################################################################################
#						trojan raw 301 - away										#
###################################################################################################################################

bind raw - 301 trojan:raw:301

proc trojan:raw:301 { from key text } {
	putlog "trojan:raw:301 -- away -- $text"
	global trojan_random_away away_time trojan_colors trojan_away_with_color trojan_badwords trojan_away_with_badword
	set nickname [lindex [split $text " "] 1]
	set nickname [string tolower $nickname]
	global botnick
	set botnic [string tolower $botnick]
	if { $nickname == $botnic } { return }
	set away [lindex [split $text ":"] end]
	if { ! [info exists ::trojan_points($nickname) ] } {
		set ::trojan_points($nickname) 0
	}
	if { [trojan:meltdown $away] } {
#		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_random_away $trojan_random_away"
		set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_random_away}]
	}
	foreach color $trojan_colors {
		if { [string match "*$color*" $away] } {
#		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_away_with_color $trojan_away_with_color"
			set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_away_with_color}]
			break
		}
	}
	foreach badword $trojan_badwords {
		if { [string match "*$badword*" $away] } {
#		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- + trojan_away_with_badword $trojan_away_with_badword"
			set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_away_with_badword}]
			break
		}
	}
	set ::away($nickname) 1
	if { $away == "" } {
		catch { unset ::away($nickname) } error
	}
	utimer $away_time [list catch { unset ::away($nickname) } error]
}


###################################################################################################################################
#						is away or not											#
###################################################################################################################################

proc away { nickname } {
	set nickname [string tolower $nickname]
	if { [info exists ::away($nickname) ] } {
		return 1
	} else {
		return 0
	}
}

###################################################################################################################################
#						trojan raw 313 - irc op										#
###################################################################################################################################

bind raw - 313 trojan:raw:313

proc trojan:raw:313 { from key text } {
	global ircop_time
	set nickname [lindex [split $text " "] 1]
	set nickname [string tolower $nickname]
	global botnick
	set botnic [string tolower $botnick]
	if { $nickname == $botnic } { return }
	if { ! [info exists ::trojan_points($nickname) ] } {
		set ::trojan_points($nickname) 0
	}
	set ::trojan_points($nickname) 0
	set ::ircop($nickname) 1
	if { $::trojan_debug_mode } {
		putlog "trojan:raw:313: $nickname is an IRC Operator"
	}
#	timer $ircop_time [list catch { unset ::ircop($nickname) } error]
}

###################################################################################################################################
#						is ircop or not											#
###################################################################################################################################

proc ircop { nickname } {
	if { [info exists ::ircop($nickname) ] } {
		return 1
	} else {
		return 0
	}
}

###################################################################################################################################
#						trojan raw 317 - idletime										#
###################################################################################################################################

bind raw - 317 trojan:raw:317

proc trojan:raw:317 { from key text } {
	global trojan_idletime trojan_less_idle
	set nickname [lindex [split $text " "] 1]
	set nickname [string tolower $nickname]
	global botnick
	set botnic [string tolower $botnick]
	if { $nickname == $botnic } { return }
	set idletime [lindex [split $text " "] 2]
	set singon [lindex [split $text " "] 3]
#	putlog "trojan: nickname: $nickname -- idletime: $idletime -- singon: $singon"
	if { ! [info exists ::trojan_points($nickname) ] } {
		set ::trojan_points($nickname) 0
	}
	if { $idletime < $trojan_idletime } {
#		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- idletime: $idletime < trojan_idletime: $trojan_idletime + $trojan_less_idle" 
		set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_less_idle}]
	}
}

###################################################################################################################################
#						trojan raw 319 - channel										#
###################################################################################################################################

bind raw - 319 trojan:raw:319

proc trojan:raw:319 { from key text } {

	global trojan_status_op trojan_status_voice trojan_status_regular trojan_status_delayed trojan_minimum_chans trojan_to_less_chans

	set nickname [lindex [split $text " "] 1]
	set nickname [string tolower $nickname]
	set chans [lindex [split $text ":"] end]

	global botnick
	set botnic [string tolower $botnick]
	if { $nickname == $botnic } { return }

	if { $::trojan_debug_mode } {
		putlog "trojan nickname: $nickname -- chans: $chans"
	}

	if { ! [info exists ::trojan_points($nickname) ] } {
		set ::trojan_points($nickname) 0
	}

	set op_channels 0
	set voice_channels 0
	set regular_channels 0
	set delay_channels 0

	set count_chans 0
	foreach channel $chans {
		set status [string index $channel 0]
		set count_chans [expr {$count_chans +1}]
		if { $status == "@" } {
			set op_channels [expr {$op_channels +1}]
		}
		if { $status == "+" } {
			set voice_channels [expr {$voice_channels +1}]

		}
		if { $status == "#" } {
			set regular_channels [expr {$regular_channels +1}]
		}
		if { $status == "<" } {
			set delay_channels [expr {$delay_channels +1}]
		}
	}

	set oppoints [expr {$op_channels * $trojan_status_op}]
	set voicepoints [expr {$voice_channels * $trojan_status_voice}]
	set regularpoints [expr {$regular_channels * $trojan_status_regular}]
	set delaypoints [expr {$delay_channels * $trojan_status_delayed}]

	set ::trojan_points($nickname) [expr {$::trojan_points($nickname) - $oppoints}]
	if { $::trojan_debug_mode } {
		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- op_channels: $op_channels -- oppoints: $oppoints"
	}

	set ::trojan_points($nickname) [expr {$::trojan_points($nickname) - $voicepoints}]
	if { $::trojan_debug_mode } {
		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- voice_channels: $voice_channels -- voicepoints: $voicepoints"
	}

	set ::trojan_points($nickname) [expr {$::trojan_points($nickname) - $regularpoints}]
	if { $::trojan_debug_mode } {
		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- regular_channels: $regular_channels -- regularpoints: $regularpoints"
	}

	set ::trojan_points($nickname) [expr {$::trojan_points($nickname) - $delaypoints}]
	if { $::trojan_debug_mode } {
		putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- delay_channels: $delay_channels -- delaypoints: $delaypoints"
	}

	lesschannel $nickname $count_chans

	if { $count_chans < $trojan_minimum_chans } {
		if { $::trojan_debug_mode } {
			putlog "trojan: nickname: $nickname -- points: $::trojan_points($nickname) -- user is only in $count_chans chans -> + $trojan_to_less_chans"
		}
		set ::trojan_points($nickname) [expr {$::trojan_points($nickname) + $trojan_to_less_chans}]
	}

}

###################################################################################################################################
#						trojan raw 318 - end whois										#
###################################################################################################################################

bind raw - 318 trojan:raw:318

proc trojan:raw:318 { from key text } {

	set nickname [lindex [split $text " "] 1]
	set nickname [string tolower $nickname]

	global botnick
	set botnic [string tolower $botnick]
	if { $nickname == $botnic } { return }

	if { ! [info exists ::trojan_points($nickname) ] } {
		set ::trojan_points($nickname) 0
	}

	trojan:after:whois $nickname $::trojan_points($nickname)

	if { [info exists ::trojan_points($nickname) ] } {
		unset ::trojan_points($nickname)
	}

}

###################################################################################################################################
#						trojan after whois											#
###################################################################################################################################

proc trojan:after:whois { nickname points } {

	global trojan_max_points

	set nickname [string tolower $nickname]
	global botnick
	set botnic [string tolower $botnick]
	if { $nickname == $botnic } { return }

	if { $::trojan_debug_mode } {
		putlog "trojan:after:whois: $nickname -- authed: [authed $nickname]"
		putlog "trojan:after:whois: $nickname -- away: [away $nickname]"
		putlog "trojan:after:whois: $nickname -- ircop: [ircop $nickname]"
		putlog "14trojan:after:whois: $nickname -- points: $points -- \/whois $nickname"
	}

	if { [ircop $nickname] } { return }
	if { [authed $nickname] } { return }
	if { $points <= 0 || $points == "" } { return }

	if { $::trojan_debug_mode } {
		putlog "4trojan:after:whois: $nickname -- points: $points -- \/whois $nickname"
	}

	if { $points >= $trojan_max_points } {
		trojan:keepout $nickname $points
	}

}

###################################################################################################################################
#						trojan remove me											#
###################################################################################################################################

proc trojan:msg:removeme { nickname hostname handle text } {
	set BUZAin "antitrojan!$hostname"
	set BUZAout [get:ban:mask $BUZAin]
#	if { [info exists ::trojanremoveme($BUZAout) ] } { return }
	if { ! [info exists ::trojanremoveme($BUZAout) ] } {
		set ::trojanremoveme($BUZAout) 1
		timer 60 [list unset ::trojanremoveme($BUZAout) ]
	}
	set addhost [maskhostxx "$nickname!$hostname" 3]
	set hand "nofloodbot"
	if { ! [validuser $hand] } {
		putlog "trojan:msg:removeme adduser $hand"
		adduser $hand
	}
	if { [validuser $hand] } {
		putlog "trojan:msg:removeme setuser $hand hosts $addhost"
		setuser $hand hosts $addhost
	}

	putserv "NOTICE $nickname :You added yourself to my userbase. I will not kick you again if you stick to this host: $addhost ."

	if { [isban $BUZAout] } { trojan:remove:globalban $BUZAout }
	if { [isban $addhost] } { trojan:remove:globalban $addhost }

	foreach channel [channels] {
		if { [validchan $channel] } {
			if { [isban $BUZAout $channel] } { trojan:remove:chanban $BUZAout $channel }
			if { [isban $addhost $channel] } { trojan:remove:chanban $addhost $channel }
		}
	}

	utimer 2 [list unban:all:channel $BUZAout]
	utimer 2 [list unban:all:channel $addhost]

}

# 1
proc trojan:remove:globalban { hostname } {
	global trojan_kick_reason
	foreach bans [banlist] {
		set ban [lindex $bans 0]
		set reason [lindex $bans 1]
		if { [string match -nocase "*$hostname*" $ban] } {
			if { [string match -nocase "*trojanbot*" $reason] } {
				killban $ban
			}
		}
	}
}

# 2
proc trojan:remove:chanban { hostname channel } {
	global trojan_kick_reason
	foreach bans [banlist $channel] {
		set ban [lindex $bans 0]
		putlog "$ban"
		set reason [lindex $bans 1]
		if { [string match -nocase "*$hostname*" $ban] } {
			if { [string match -nocase "*trojanbot*" $reason] } {
				killchanban $channel $ban
			}
		}
	}
}

###################################################################################################################################
#						trojan keepout											#
###################################################################################################################################

proc trojan:keepout { nickname points } {

	global trojan_kick_reason botnick trojan_ban trojan_kick trojan_debugmode trojan_testchan
	global trojan_newchan_bantime trojan_newchanban trojan_newban trojan_newban_bantime

	set handle [nick2hand $nickname]

	if { [string equal -nocase $::botnick $nickname] } { return }
	if { [string equal -nocase $handle "nofloodbot"] } { return }
	if { $trojan_goodwords != "" } {
		foreach nobadword $trojan_goodwords {
			if { [string match -nocase $nobadword $nickname] } {
				return
			}
		}
	}
	if { [string match -nocase "*.users.quakenet.org*" $hostname] } { return }
	if { [matchattr handle mnofvI|mnofvI $channel] } { return }

	set id [id $trojan_testchan]

	regsub -all -- {:id:} $trojan_kick_reason $id trojan_kick_reason
	regsub -all -- {:botnick:} $trojan_kick_reason $botnick trojan_kick_reason
	regsub -all -- {:points:} $trojan_kick_reason $points trojan_kick_reason
	set trojan_kickmsg $trojan_kick_reason

#	append trojan_kickmsg " And please type: /msg $botnick removeme 1 :: badpoints: $points :: ID: $id ::.."

	set host [getchanhost $nickname]
	set BUZAin "trojankeepout!$host"
	set hostname [get:ban:mask $BUZAin]

	if { [isban $hostname] } { return }

	foreach channel [channels] {
#		if { ! [isop $botnick $channel] } { continue }
		if { ! [channel get $channel antitrojan] } { continue }
		if { ! [onchan $nickname $channel] } { continue	}
		if { [isban $hostname $channel] } { continue }
		if { $trojan_debugmode } {
#			putlog "newchan:ban $channel $hostname antitojan.tcl $trojan_kickmsg $trojan_newchan_bantime"
#			putlog "new:ban $channel $hostname antitojan.tcl $trojan_kickmsg $trojan_newban_bantime"
#			putlog "0,4trojan:keepout: put:quick $channel +b $hostname"
			putlog "0,4trojan:keepout: kick:user $nickname $channel $trojan_kickmsg"
		}
		if { $trojan_ban } {
			put:quick $channel +b $hostname
		}
		if { $trojan_kick } {
			flood:detect $channel
			kick:user $nickname $channel $trojan_kickmsg
		}
		if { $trojan_newchanban } {
			newchan:ban $channel $hostname "antitojan.tcl" $trojan_kickmsg $trojan_newchan_bantime
		}
		if { $trojan_newban } {
			new:ban $channel $hostname "antitojan.tcl" $trojan_kickmsg $trojan_newchan_bantime
		}
	}
}

###################################################################################################################################
#						Copyright / Putlog											#
###################################################################################################################################

putlog "*** antitrojan.tcl by sKy\\ - #apache-root @ Quakenet loaded. ***"
# This script is under GNU General Public License! For more infos see in the script header!

User avatar
sKy
Op
Posts: 194
Joined: Thu Apr 14, 2005 5:58 pm
Location: Germany

Post by sKy »

This part is need to run the script.

Code: Select all


# -+--+--+--+--+--+
# copyright:
# -+--+--+--+--+--+

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

# Remember removing copyright is lame...

# mytools.tcl by sKy\ #Apache-root @ irc.quakenet.org
set mytools_version 0.6
# version $mytools_version ^^

# -+--+--+--+--+--+
# end copyright:
# -+--+--+--+--+--+

# well, this file is always in developement and uses procs which i need in most of my scripts.

###################################################################################################################################
#					variables (no changes needed)										#
###################################################################################################################################

set new_chan_ban_after 5

set whois_again 1

setudef flag moded

set flood_detect 1

set floods 6

set fsecs 30

###################################################################################################################################
#					ip2nick													#
###################################################################################################################################

# set nicklist [ip2nick $fullhost]

proc ip2nick { fullhost } {
	global lastbind botnick
	if { ! [string match -nocase "*!*@*" $fullhost] } {
		putlog "ip2nick error: fullhost: $fullhost - lastbind: $lastbind"
		return 1
	}
	set hostname [lindex [split $fullhost "@"] 1]
	foreach channel [channels] {
		if { [onchan $botnick $channel] } {
			foreach user [chanlist $channel] {
				set userhost [getchanhost $user]
				set uh [lindex [split $userhost "@"] 1]
				if { [string match -nocase "*$hostname*" $uh] } {
					if { ! [info exists ::allready_ip_to_nick_list($user) ] } {
						set ::allready_ip_to_nick_list($user) 1
						utimer 10 [list unset ::allready_ip_to_nick_list($user) ]
						append nicklist "$user "
				 	}
				}
			}
		}
	}
	return $nicklist
}

###################################################################################################################################
#					unbann in all chans												#
###################################################################################################################################

proc unban:all:channel { hostname } {
	global botnick
	set BUZAout $hostname
	if { ! [isban $hostname] } {
		foreach channel [channels] {
			if { [isop $botnick $channel] } {
				if { ! [isban $hostname $channel] } {
					if { ! [info exists ::nobanremove($channel,$BUZAout) ] } {
						if { [ischanban $hostname $channel] } {
							pushmode $channel -b $hostname
						}
					}
				}
			}
		}
	}
}

###################################################################################################################################
#					bind msgm													#
###################################################################################################################################

set procs_msgm {
	silence:msgm
	netsplit:msgm
	spam:scan:private
}

bind msgm - * msgm

proc msgm { nickname hostname handle text } {
	global procs_msgm
	set BUZAin "msgm!$hostname"
	set BUZAout [get:ban:mask $BUZAin]
	foreach command $procs_msgm {
		if { [info command $command] != "" } { $command $nickname $BUZAout $handle $text }
	}
}

###################################################################################################################################
#					bind join													#
###################################################################################################################################

set procs_join {
	check:joinflood
	floodbot:join
	clanmatch:css:join
	randomauth:join
	trojan:join
	vipop:join
	peak:join
	vip:check:status
	regop:pushit
	ao:pushit
	av:pushit
	IRCopScanOnJoin
}

bind join - * bind:join

proc bind:join { nickname hostname handle channel } {
	global procs_join
	set BUZAin "join!$hostname"
	set BUZAout [get:ban:mask $BUZAin]
	foreach command $procs_join {
		if { [info command $command] != "" } { $command $nickname $BUZAout $handle $channel }
	}
}


###################################################################################################################################
#					bind ctcp / ctcr												#
###################################################################################################################################

bind ctcp - * ctcp
bind ctcr - * ctcp

set procs_ctcp_action {
	antiadvertise:ctcp
	f:check:ctcp
	repeat:check:ctcp
	retardkicker:ctcp
	badword::ctcp
	log:cact
	action:abuse
}

set procs_ctcp_noaction {
	ctcp:flod:prot
	spam:scan:ctcp
	silence:ctcp
}

proc ctcp { nickname hostname handle dest keyword text } {
	if { [spam:scan:validuser $nickname $hostname $handle] } { return 0 }
	global procs_ctcp_action procs_ctcp_noaction
	set BUZAin "ctcp!$hostname"
	set BUZAout [get:ban:mask $BUZAin]
	if { [string match -nocase "*action*" $keyword] } {
		foreach command $procs_ctcp_action {
			if { [info command $command] != "" } { $command $nickname $BUZAout $handle $dest $keyword $text }
		}
	}
	if { ! [string match -nocase "*action*" $keyword] } {
		foreach command $procs_ctcp_noaction {
			if { [info command $command] != "" } { $command $nickname $BUZAout $handle $dest $keyword $text }
		}
	}
	return 1
}

###################################################################################################################################
#					bind pubm													#
###################################################################################################################################

set pub_procs {
	f:check
	antiadvertise:pub
	masshighlight
	badword:msg
	check:masshl
	repeat:check
	::badword::sentry
	retardkicker:pub
	chk:worm
	et:relay:pubmsgstart
	urlcheck
}

bind pubm - * pubm

proc pubm { nickname hostname handle channel text } {
	global pub_procs
#	if { [spam:scan:validuser $nickname $hostname $handle] } { return 0 }
	set BUZAin "pub!$hostname"
	set BUZAout [get:ban:mask $BUZAin]
	foreach command $pub_procs {
		if { [info command $command] != "" } { $command $nickname $BUZAout $handle $channel $text }
	}
}

###################################################################################################################################
#					bind notc													#
###################################################################################################################################

set procs_notc {
	not:flood
	spam:scan:notice
	silence:notc
}

bind notc - * notc

proc notc { nickname hostname handle text dest } {
	global procs_notc
	set BUZAin "notc!$hostname"
	set BUZAout [get:ban:mask $BUZAin]
	foreach command $procs_notc {
		if { [info command $command] != "" } { $command $nickname $BUZAout $handle $text $dest }
	}
}

###################################################################################################################################
#					bind nick													#
###################################################################################################################################

set procs_nick {
	trojan:nickchange
	check:nickflood
}

bind nick - * bind:nick

proc bind:nick { nickname hostname handle channel newnick } {
	global procs_nick
	set BUZAin "nick!$hostname"
	set BUZAout [get:ban:mask $BUZAin]
	foreach command $procs_nick {
		if { [info command $command] != "" } { $command $nickname $BUZAout $handle $channel $newnick }
	}
}

###################################################################################################################################
#					channel limit													#
###################################################################################################################################

proc limit { channel } {
	set channelmodes [getchanmode $channel]
	set modes [lindex [split $channelmodes " "] 0] 
	if { [string match "*k*" $modes] && [string match "*l*" $modes] } {
		set key [lindex [split $channelmodes " "] 1] 
		set limit [lindex [split $channelmodes " "] 2] 
		return $limit
	}
	if { [string match "*k*" $modes] } {
		set limit 0
		set key [lindex [split $channelmodes " "] 1] 
		return $limit

	}
	if { [string match "*l*" $modes] } {
		set limit [lindex [split $channelmodes " "] 1]
		set key ""
		return $limit

	}
	set key ""
	set limit 0
	return $limit
}

###################################################################################################################################
#					channel key													#
###################################################################################################################################

proc key { channel } {
	set channelmodes [getchanmode $channel]
	set modes [lindex [split $channelmodes " "] 0] 
	if { [string match "*k*" $modes] && [string match "*l*" $modes] } {
		set key [lindex [split $channelmodes " "] 1] 
		set limit [lindex [split $channelmodes " "] 2] 
		return $key
	}
	if { [string match "*k*" $modes] } {
		set limit 0
		set key [lindex [split $channelmodes " "] 1] 
		return $key

	}
	if { [string match "*l*" $modes] } {
		set limit [lindex [split $channelmodes " "] 1]
		set key ""
		return $key

	}
	set key ""
	set limit 0
	return $key
}

###################################################################################################################################
#					whois													#
###################################################################################################################################

proc whois { nickname hostname channel } {

	if { [isban $hostname] } { return }
	if { [isban $hostname $channel] } { return }

	global whois_again
	if { ! [info exists ::allready_whoised($nickname) ] } {
		set ::allready_whoised($nickname) 1
		putquick "WHOIS 1 $nickname"
		utimer $whois_again [list unset ::allready_whoised($nickname)]
	}

}

###################################################################################################################################
#					putnow / putdccraw												#
###################################################################################################################################

proc putnow { a } { 
	append a "\r\n" 
	putdccraw 0 [string length $a] $a 
}

###################################################################################################################################
#					put:quick new queue												#
###################################################################################################################################

# 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 put:quick:1 { channel what {target ""} } {
	if { $target == "" } {
		pushmode $channel $what
		return
	} else {
		pushmode $channel $what $target
		return
	}
}

proc put:quick:2 { channel what {target ""} } {
	if { ! [info exists ::put_quick($channel,$what,$target) ] } {
		set ::put_quick($channel,$what,$target) 1
		utimer 5 [list unset ::put_quick($channel,$what,$target)]
		if { $target == "" } {
			putquick "MODE $channel $what" -next
			return
		} else {
			putquick "MODE $channel $what $target" -next
			return
		}
	}
}


proc put:quick { channel what {target ""} } {
	set plus_or_minus [string index $what 0]
	set modechange [string index $what 1]
	if { $channel == "PRIVMSG" } {
		put:quick:private $channel $what $target
	}
	if { $channel == "NOTICE" } {
		put:quick:private $channel $what $target
	}
	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" } {

			pushmode $channel -b $target

#			putquick:unban $channel $target
#			return
		}
		if { $modechange == "v" } {
			putquick:devoice $channel $target
			return
		}
		putquick:mode $channel $what
	}
}

proc put:quick:private { channel what target } {
	set put "$channel $what :$target"
	putquick $put -next
}

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: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) ""
	}
}

proc put:quick:input { channel what {target ""} } {

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

proc 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) ""
	}
	global put_quick_refresh botnick
	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 != "" } {
		if { [isop $botnick $channel] } {
#			putnow "MODE $channel $change"
			putquick "MODE $channel $change" -next
		}
		put:quick:clearqueue $channel
	}
#	after $put_quick_refresh [list put:quick:pushnow $channel]
}


proc put:quick:loop { } {
	global put_quick_refresh botnick
	foreach channel [channels] {
		if { [channel get $channel inactive] } { continue }
 		put:quick:pushnow $channel
	}
	after $put_quick_refresh [list put:quick:loop]
}


if { ! [info exists ::allready_started_put_quick_loop ] } {
	set ::allready_started_put_quick_loop 1
	put:quick:loop
}

###################################################################################################################################
#					script load													#
###################################################################################################################################
# usage:
# .s scriptname
# not .s scriptname.tcl

bind dcc n|- s script:load
proc script:load { handle idx text } {
	if { [catch { uplevel #0 [list source scripts/$text.tcl] } error] } {
		putlog "0,4Error while loading $text -- Errormsg: $error"
		putlog "script: $text -- ::errorInfo: $::errorInfo"
		return
	} 
	putlog "script: $text -- loaded without error."
	return
}


###################################################################################################################################
#					die														#
###################################################################################################################################
# idea by cybex #tcl @ quakenet

if { [info command die_new] == "" } {
	rename die die_new
	proc die { {text ""} } {
		if { $text == "" } {
			set text "no reason"
		}
		die_new $text
	}
}

###################################################################################################################################
#					isban:test													#
###################################################################################################################################
# isban:test $banmask $channel
# old proc, should ne be needed :P

proc isban:test { ISBANin channel } {
	foreach bans [chanbans $channel] { 
		set mask [lindex $bans 0] 
		if {[string match -nocase $ISBANin $mask]} { 
			return "ISBAN"
		 } 
	}
	return "ISNOTBAN"
}

###################################################################################################################################
# 					Spam Log													#
###################################################################################################################################

proc spam:log { nickname hostname BUZAout channel filename type abuse } {
	if { [info exists ::allready_logged($BUZAout) ] } {
		return
	}
	if { ! [info exists ::allready_logged($BUZAout) ] } {
		set ::allready_logged($BUZAout) 1
		timer 5 [list unset ::allready_logged($BUZAout) ]
	}
	set ident [lindex [split $hostname "@"] 0]
	set abuse [stripcodes uacgbr $abuse]
	set unixtime [unixtime]
	set spamtime [ctime $unixtime]
	set date [string trim [lindex $spamtime 2]]
	set month [string trim [lindex $spamtime 1]]
	set time [string trim [lindex $spamtime 3]]
	set spam_log_info "nick: $nickname •• host: $hostname •• ident: $ident •• BUZAout: $BUZAout •• channel: $channel •• type: $type •• abuse: $abuse •• $date $month $time"
	set spam_log_filename $filename
	set spam_log_file [open $spam_log_filename "a"] 
	puts $spam_log_file $spam_log_info
	close $spam_log_file
}

# old proc....
proc spam:scan:log { nickname hostname BUZAout type text {channel ""} {texte ""} } {
	if { $type == "private" } { set x "spamscan" }
	if { $type == "notice" } { set x "spamscan" }
	if { $type == "invite" } { set x "spamscan" }
	if { $type == "ctcp" } { set x "spamscan" }
	if { $type == "flood" } { set x "flood" }
	if { $x == "spamscan" } {
		spam:log $nickname $hostname $BUZAout $channel "spamscan.txt" $type "spam"
	}
	if { $x == "flood" } {
#		spam:log $nickname $hostname $BUZAout $channel "flood.txt" $type "flood"
	}
}

###################################################################################################################################
# 					Valid user													#
###################################################################################################################################

proc spam:scan:validuser { nickname hostname handle } {
	global botnick botname server
	if { [matchattr $handle bnmfo] } { return 1 }
	if { $nickname == $server } { return 1 }
	if { $nickname == $botnick } { return 1 }
	if { $hostname == $server } { return 1 }
	if { $hostname == $botname } { return 1 }
	if { $hostname == "" } { return 1 }
	if { $nickname == "" } { return 1 }
	return 0
}

###################################################################################################################################
#					expire														#
###################################################################################################################################
# set expire [expire $bantime]
# returns: date and time of expire

proc expire { bantime } {
	set expire [strftime "%d.%m.%y, %H:%M" [expr { $bantime * 60 + [unixtime] } ]]
	return $expire
}

###################################################################################################################################
#			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] } {
		put:quick $channel $what $target
		return
	}
	set servicebot [channel get $channel servicebot]
	if { $servicebot != "Q" } {
		put:quick $channel $what $target
		return
	}
	set result [isban:test $target $channel]
	if { $result == "ISBAN" } {
		if { [info exists ::pushmodeminusban($channel,$target) ] } {
			return
		}
		if {! [info exists ::pushmodeminusban($channel,$target) ] } {
			putquick "PRIVMSG Q :bandel $channel $target" -next
			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] } {
		put:quick $channel $what $target
		return
	}
	set servicebot [channel get $channel servicebot]
	if { $servicebot != "Q" } {
		put:quick $channel $what $target
		return
	}
	set result [isban:test $target $channel]
	if { $result == "ISNOTBAN" } {
		if { [info exists ::pushmodeplusban($channel,$target) ] } {
			return
		}
		if {! [info exists ::pushmodeplusban($channel,$target) ] } {
			putquick "PRIVMSG Q :ban $channel $target" -next
			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												#
###################################################################################################################################
# if a user join which is on global or channel banlist
# this script will faster ban them and if them join
# "in the same time" the bot will collect the modechanges
# 
# if you dislike just do not bind

bind join - * banned:user:join
bind nick - * banned:user:nickchange

proc banned:user:nickchange { nickname hostname handle channel newnick } {
	global botnick
	if { ! [validchan $channel] } { return }
	if { $nickname == $botnick } { return }
	if { $newnick == $botnick } { return }
	if { $channel == "*" } { return }
	set nickname $newnick
	banned:user:join $nickname $hostname $handle $channel
}

proc banned:user:join { nickname hostname handle channel } {
	if { ! [validchan $channel] } { return }
	set hostname "$nickname!$hostname"
	set banmask ""
	foreach ban [banlist $channel] {
		set host [lindex [split $ban] 0]
		set reason [lindex $ban 1]
		if { [string match -nocase $host $hostname] } {
			set banmask $host
		}
		if { $banmask != "" } {
			banned:user:getout $nickname $hostname $handle $channel $banmask $reason
			return
		}
	}
	foreach ban [banlist] {
		set host [lindex [split $ban] 0]
		set reason [lindex $ban 1]
		if { [string match -nocase $host $hostname] } {
			set banmask $host
		}
		if { $banmask != "" } {
			banned:user:getout $nickname $hostname $handle $channel $banmask $reason
			return
		}
	}
}

proc banned:user:getout { nickname hostname handle channel banmask reason } {
	flood:detect $channel
	put:quick $channel +b $banmask
	set channelmodes [getchanmode $channel]
	if { [channel get $channel moded] } {
		if { [string match -nocase "*d*" $channelmodes] } {
			kick:user $nickname $channel $reason
		}
	}
}

###################################################################################################################################
#					get:ban:mask													#
###################################################################################################################################
# ussage: get:ban:mask nick!user@host $channel
# return: better hostmask

set dynhosts {
		"*.proxad.net"
		"*chello*"
		"*kabelbw*"
		"*mediaways*"
		"*arcor*"
		"*ipconnect*"
		"*dsl*"
		"*wanadoo*"
		"*dial*in*"
		"*.aol.com"
		"*.telia.com"
		"*.gaoland.net"
		"*.telenet.be"
		"*.noos.fr"
		"*.tvcablenet.be"
		"*.tiscali.*"
		"*.comcast.net"
		"*.charter-stl.com"
		"*.mindspring.com"
		"*.attbi.com"
		"*.btcentralplus.com"
		"*.netvision.net.il"
		"*.optonline.net"
		"*.rcn.com"
		"*.primacom.net"
		"*.numericable.fr"
		"*.cust.tele2.fr"
		"*.ikexpress.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"
		"*.Level1.net"
		"*.telia.com"
		"*.quickclic.net"
		"*.ewetel.net"
		"*.rogers.com"
		"*.ntl.com"
		"*.verizon.net"
		"*.bezeqint.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"
		"*.dsl.inet.fi"
		"*.elisa-laajakaista.fi"
		"*.dnainternet.fi"
		"*.pppool.de"
		"*.finet.se"
		"*.arcor-ip.net"
		"*.umea.se"
		"*.vnet.hu"
		"*.interbusiness.it"
		"*.webspeed.dk"
		"*.home.nl"
		"*.songnetworks.se"
		"*.bluecom.no"
		"*.btopenworld.com"
		"*.invitel.hu"
		"*.optusnet.com.au"
		"*.qsc.de"
}
set dynhosts [string tolower $dynhosts]
# set dynhosts [string map {"*" ""} $dynhosts]
set dynhosts [lrange $dynhosts 0 end]
set dynhosts [lsort $dynhosts]

# script for setting up a optimal banmask
proc get:ban:mask { BUZAin } {
	global dynhosts
       set BUZAin [string map {~ ""} $BUZAin]
	if { ! [string match -nocase "*!*@*" $BUZAin] } {
		global lastbind
		putlog "get:ban:mask error- BUZAin: $BUZAin -- lastbind: $lastbind"
		return "error!*@*"
	} else {
	      	set BUZA [lindex [split $BUZAin "!"] 1]
      		set BUZAout "*!*$BUZA"
		set BUZA [lindex [split $BUZAin "@"] 1]
		if { [string match -nocase "*.users.quakenet.org*" $BUZAin] } {
			return *!*@$BUZA
		}
		foreach host $dynhosts {
			if { [string match -nocase $host $BUZAin] } {
				return *!*@$BUZA
			}
		}
	       return $BUZAout
	}
}

#	set hostname [string tolower $hostname]
proc getbanmask { hostname } {
	global dynhosts

	set endhost "*$hostname*"
	set pos [lsearch -glob $dynhosts $endhost]
	putlog "pos $pos"
	if { $pos != -1 } {
		return "*!*@[lindex [split $hostname "@"] 1]"
	} else {
		return "*!$hostname"
	}	

}

#	set host [split $hostname "."]
#	set llength [llength $host]
#	set last [lindex $host [expr $llength -1]]
#	set pre [lindex $host [expr $llength -2]]
#	set endhost "*$pre.$last*"


###################################################################################################################################
#					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 x [string match -nocase $mask $::botname]
		if { $x == 1 } { lappend matchlist $mask }
	}
	return $matchlist
}

###################################################################################################################################
#					kick:user													#
###################################################################################################################################
# usage: kick:user $nickname $channel $kickmsg
# 

set kick_floodprot 10

proc kick:user { nickname channel kickmsg } {
	global kick_floodprot
	if { [info exists ::allready_kicked($channel,$nickname) ] } {
		return
	}
	if { ! [info exists ::allready_kicked($channel,$nickname) ] } {
		set ::allready_kicked($channel,$nickname) 1
		utimer $kick_floodprot [list unset ::allready_kicked($channel,$nickname) ]
	}
	if { [onchan $nickname $channel] } {
		catch { putkick $channel $nickname $kickmsg } error
		return
	} else {
		set channelmodes [getchanmode $channel]
		if { [channel get $channel moded] } {
			if { [string match -nocase "*d*" $channelmodes] } {
				putlog "kick:user: putserv KICK $channel $nickname :$kickmsg"
				utimer 1 [list putnow "KICK $channel $nickname :$kickmsg"]
			}
		}
	}
}

###################################################################################################################################
#					newchan:ban													#
###################################################################################################################################

proc newchan:ban { channel hostname creator comment lifetime } {
	if { ! [isban $hostname $channel] } { 
		newchanban $channel $hostname $creator $comment $lifetime
		return
	} else { 
		foreach ban [banlist $channel] {
			if { [string match -nocase "*[lindex $ban 0]*" $hostname] } {
				set expire [lindex $ban 2]
				if { $expire == 0 } { break ; return }
				set remain [expr { $expire - [unixtime] } ]
				set remain [expr { $remain / 60 } ]
				if { $remain > $lifetime } { break ; return }
				newchanban $channel $hostname $creator $comment $lifetime
			}
		}
	}
}

###################################################################################################################################
#					new:ban													#
###################################################################################################################################
# new:ban $BUZAout $creator $comment $lifetime

proc new:ban { hostname creator comment lifetime } {
	if { ! [isban $hostname] } { 
		newban $hostname $creator $comment $lifetime
		return
	} else { 
		foreach ban [banlist] {
			if { [string match -nocase "*[lindex $ban 0]*" $hostname] } {
				set expire [lindex $ban 2]
				if { $expire == 0 } { break ; return }
				set remain [expr { $expire - [unixtime] } ]
				set remain [expr { $remain / 60 } ]
				if { $remain > $lifetime } { break ; return }
				newban $hostname $creator $comment $lifetime
			}
		}
	}
}

###################################################################################################################################
#					flood detect													#
###################################################################################################################################
# usage: flood:detect $channel
# 

proc flood:detect { channel } {
	global floods fsecs botnick flood_detect
	if { ! $flood_detect } { return }
	if { ! [isop $botnick $channel] } { return }
	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 { [string match "*m*" $modes] } { put:quick $channel -m }
}
proc flood:detect:minus:r { channel } {
	global botnick
	set modes [getchanmode $channel]
	if { [string match "*r*" $modes] } { put:quick $channel -r }
}

###################################################################################################################################
#					lsearch													#
###################################################################################################################################
# usage: set list [lremove $list $varname]
# will remove a variable, might me useful
# proc sponserd by thommey
proc lremove { list what } {
	while { [set pos [lsearch -exact $list $what]] != -1 } {
			set list [lreplace $list $pos $pos]
		}
	return $list
}

###################################################################################################################################
#					manuel:banremove												#
###################################################################################################################################

proc manuel:banremove { nickname hostname handle channel mode victim } {
	global botnick
	if { $nickname == $botnick } { return }
	if { $nickname == $::server } { return }
	if { $nickname == ""} { return }
	if { $nickname == "Q"} { return }
	if { $nickname == "L"} { return }
	if { $victim == "L"} { return }	
	if { $victim == "Q"} { return }
	if { [matchattr $handle bB|- $channel] } { return }
	if {  [matchattr $handle nmo|nmo $channel] } { return }
	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 :1$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 :1$warnsubg" }
	}
}

###################################################################################################################################
#					banremove													#
###################################################################################################################################
# usage: badall:banremove $hostname $channel
# will remove a channel ban only if the isn`t in global or channelbanlist

proc badall:banremove { BUZAout channel } {
	if { [isban $BUZAout] } { return }
	if { [isban $BUZAout $channel] } { return }
	if { [info exists ::nobanremove($channel,$BUZAout) ] } {
		return
	}
	put:quick $channel -b $BUZAout
}

###################################################################################################################################
#					Kickcounter													#
###################################################################################################################################
# usage:
# set id [id $channel]	- returns counter and sets id +i

setudef str kickcounter

# old proc
proc kc { channel } {
	return
}

proc id:plus { channel } {
	set counter [channel get $channel kickcounter]
	if { $counter == "" } { set counter 0 }
	set counter [expr { $counter +1 } ]
	channel set $channel kickcounter $counter
}

proc id { channel } {
	set countchan [channel get $channel kickcounter]
	if { $countchan == "" } { set countc 0 }
	set allchans 0
	foreach chan [channels] {
		set countc [channel get $chan kickcounter]
		if { $countc == "" } { set countc 0 }
		set allchans [expr { $allchans + $countc } ]
	}
	set id "$allchans\/$countchan"
	id:plus $channel
	return $id
}


###################################################################################################################################
#					escape														#
###################################################################################################################################

proc clean { i } {
	  regsub -all -- {([\(\)\[\]\{\}\$\"\\])} $i {\\\1} i
	  return $i
}

###################################################################################################################################
#					strip colors													#
###################################################################################################################################

proc nocolor { str } {
	regsub -all -- {\003[0-9]{0,2}(,[0-9]{0,2})?|\017|\037|\002|\026|\006|\007} $str "" str
	return $str
}

###################################################################################################################################
#					copyright													#
###################################################################################################################################

putlog "*** Mytools.tcl version: $mytools_version by sKy loaded. ***"
# This script is under GNU General Public License! For more infos see in the script header!

User avatar
demond
Revered One
Posts: 3073
Joined: Sat Jun 12, 2004 9:58 am
Location: San Francisco, CA
Contact:

Post by demond »

you should have read this first
User avatar
Alchera
Revered One
Posts: 3344
Joined: Mon Aug 11, 2003 12:42 pm
Location: Ballarat Victoria, Australia
Contact:

Post by Alchera »

demond wrote:you should have read this first
Ummm... That requires an effort! Something not used these days it seems.
Add [SOLVED] to the thread title if your issue has been.
Search | FAQ | RTM
User avatar
awyeah
Revered One
Posts: 1580
Joined: Mon Apr 26, 2004 2:37 am
Location: Switzerland
Contact:

Post by awyeah »

I released a similar script for random/drone nicks earlier, here take a look:
http://www.awyeah.org/scripts/dronenick.zip
·­awyeah·

==================================
Facebook: jawad@idsia.ch (Jay Dee)
PS: Guys, I don't accept script helps or requests personally anymore.
==================================
User avatar
sKy
Op
Posts: 194
Joined: Thu Apr 14, 2005 5:58 pm
Location: Germany

Post by sKy »

demond wrote:you should have read this first
I read it before and the topic was something like 'Meltdowns Nickcheck against Floodbotsnicks'.

awyeah`s script has a little bit higher error rate. But it seams be really fast and good.

My script performes a /whois before, errorrate is > 2-5% but it`s 2-4 seconds slower. It`s desinged against trojanbots (automatic bot which run on hacked computers) which use random nicknames and not against mass proxy flood etc.
User avatar
demond
Revered One
Posts: 3073
Joined: Sat Jun 12, 2004 9:58 am
Location: San Francisco, CA
Contact:

Post by demond »

I keep wondering where do you get your numbers from... here and in another thread... did you actually make some kind of profiling or measurements/calculations of any kind to come up with those numbers?
User avatar
Thunderdome
Op
Posts: 187
Joined: Tue Mar 15, 2005 4:42 pm

Post by Thunderdome »

awyeah, not meaning to be mean... I use your script and it does not work very well. keeps kicking people who are not drones, and are perfectly ok...
it could use more work.
User avatar
Alchera
Revered One
Posts: 3344
Joined: Mon Aug 11, 2003 12:42 pm
Location: Ballarat Victoria, Australia
Contact:

Post by Alchera »

Thunderdome wrote:awyeah, not meaning to be mean... I use your script and it does not work very well. keeps kicking people who are not drones, and are perfectly ok...
it could use more work.
Do you even know what a "drone" nick is? Are you fully aware that a user added to the bot with one of those stupid nicks is protected from punishment?

I suggest more study on your part before making such comments. :P
Add [SOLVED] to the thread title if your issue has been.
Search | FAQ | RTM
User avatar
sKy
Op
Posts: 194
Joined: Thu Apr 14, 2005 5:58 pm
Location: Germany

Post by sKy »

Oh no, I like criticism! That was the reason for posting here.

He is right. I 'released' this test version to fast. I forgot to think about much things.

(Examples:
- Quakenet: /whois 1 nickname or /whois nickname nickname and the server will reply the "normal whois" + idletime. On gamesurge you have to use /whois nickname, otherwise you get an error.
- Nicklenght: 10-32 (i am unsure but i have seen really huge on some networks).
I missed to think about some things.)

The script has a debug mode, which means everything will be shown on partyline without that the bot will do some kick/bans. I suggest to test it before ;/.

Under this contions i can`t suggest to use it. It seams just to work ok for myself.

AllFloodProtection.tcl by Sir_Fz or dronenick.tcl by awyeah might be a better solution.

Anyway, feel free to test it in debugmode. Suggestions and critism about tcl and the way of detection are welcome.
User avatar
Alchera
Revered One
Posts: 3344
Joined: Mon Aug 11, 2003 12:42 pm
Location: Ballarat Victoria, Australia
Contact:

Post by Alchera »

sKy wrote:AllFloodProtection.tcl by Sir_Fz or dronenick.tcl by awyeah might be a better solution.
Why not take a look at their respective codes and see what ideas you may find for your script? Is good to look at other people's code especially if you get stuck and need an idea on how to tackle a particular problem without actually using their code. :)

Is what it's all about. :mrgreen:
Add [SOLVED] to the thread title if your issue has been.
Search | FAQ | RTM
User avatar
awyeah
Revered One
Posts: 1580
Joined: Mon Apr 26, 2004 2:37 am
Location: Switzerland
Contact:

Post by awyeah »

Thunderdome wrote:awyeah, not meaning to be mean... I use your script and it does not work very well. keeps kicking people who are not drones, and are perfectly ok...
it could use more work.
One of the nick scorer modules is quite harsh, I know. There is a 5% chance innocent people can get kicked. Best thing is not to place bans when kicked. Drone nicks do no join back, however a real user can join in back.

What you can do is exempt specific masks from a nick or shut down that module. There are 3 types of different detections, just turn that one off which is kicking alot of innocent people.

I have put alot of work into the script and wasted alot of time on it, I don't beleive it can be more better than this.
·­awyeah·

==================================
Facebook: jawad@idsia.ch (Jay Dee)
PS: Guys, I don't accept script helps or requests personally anymore.
==================================
User avatar
awyeah
Revered One
Posts: 1580
Joined: Mon Apr 26, 2004 2:37 am
Location: Switzerland
Contact:

Post by awyeah »

Also Sir_Fz's allprotection script's drone nick remover is just a tcl re-write of Oz Nosense Nick Remover. What I basically want todo here is to deal with vowels also.

There are 26 alphabets in ABC, and 6 vowels, "aeiouy". Mostly random nicks do not contain vowels, as there is a chance that the 6 vowels from the total 26 are not involved in some cases. But sometimes yes they do contain them, and sometimes more than twice also.

My drone nick kick has 3 types of detections.

1) Nick scorer: demonds detection system for spambuster and + one of my own developed nick scorer (which can be a bit harsh)

2) Nick matching: normal nick matching through patterns which you can specify 2, 3, 4 length patterns, within a huge list + Oz Nosense Nick Remover pattern matching.

3) Regular expression matching: Matching for special characters in nicks, no vowels or less than 3 vowels, no numbers included or not more than 2 numbers included.
·­awyeah·

==================================
Facebook: jawad@idsia.ch (Jay Dee)
PS: Guys, I don't accept script helps or requests personally anymore.
==================================
User avatar
awyeah
Revered One
Posts: 1580
Joined: Mon Apr 26, 2004 2:37 am
Location: Switzerland
Contact:

Post by awyeah »

The best drone nick catching logic can contain 2 string match or regexp logics as mentioned:

Code: Select all

if {([string length $nick] >= 4) && ([string length $nick] <= 11) && ![string match -nocase {*[aeiouy]*} $nick] && ![string match -nocase {*[0-9]*} $nick]} {
You can also replace $nick by $ident by adding 2 more logics to make it fool proof, and set it to lower case if you want more accuracy -- since most random nicks are in lower case.
·­awyeah·

==================================
Facebook: jawad@idsia.ch (Jay Dee)
PS: Guys, I don't accept script helps or requests personally anymore.
==================================
User avatar
Thunderdome
Op
Posts: 187
Joined: Tue Mar 15, 2005 4:42 pm

Post by Thunderdome »

Code: Select all

I have put alot of work into the script and wasted alot of time on it, I don't beleive it can be more better than this
Indeed... :)
One can see that...
I like the ideia, and it all sounds perfect, but somehow I had spam bots coming in that were not detected... they use regular names and idents now... :\
I've added most people in my chanserv access list to that "excluded" nicks option...
I think what you use depends also on the language... portuguese is different from english... and another thing, sometimes people simply put wouqlijewqlkjheie as an ident... and bam! :P you're out! :)
Perhpas it could focus moe on the way a spam bot behaves... for examples, seeing if that nick sends pub to the channel or to the bot... if it is in certain channels... not for all nicks, but for one nick the soon it is a "suspect"... kinda like a barrier before final punishment...
Perhap I am not making any sense... lol
Post Reply