# Protection, Anti Inviter (prot_inviter.tcl)
# Modified by nukie (02 Dec 2001) - http://nukie.front.ru/

# what host allowed to invite?
set invite_allow {
  "*dal.net"
  "SoulNet"
  "Mbee"
  "Ranyta"
}
# what words considered as an invite?
set invite_words {
  "join"
  "/join"
  "/j"
  "#*"
  "http://"
  "ftp://"
 "*.htm"
 "*.html"
 "*www.*"
 "h??p:/*"
 "h ? ? p :*"
 "*.to/*"
 "*.at/*"
 "com*#*"
 "*channel*#*"
 "*/server*"
 "ke #*"
 "di #*"
}
# what kick reason do you want to use?
set invite_kmsgs {
  "mass msg/inv/adv detected from host"
}
# what warn msg do you want to use?
set invite_amsgs {
  "mass msg/inv/adv detected from host"
}
# do you want to kick ops too?
set inv_banop 0
# bantime (in min) to ban inviters
set invite_bantm 30
# do you want to ignore inviters too?
set invite_ignore 0

set invite_clstat 1
# set cycle time in mins
set invite_cycle 20
# set channel to cycle for inviters for
#set invchk_chans {
"#pakam"
#}

set invnotcop 0

# Nicks to notify when the bot isn't opped in channel
set invopnicks {
  "SoulNet"
}

#set invprotloaded 1

# This is for your benefit hehe ;), you can either set your own LOGO here, your logo will appear-
# when the bot notice you, or when it makes msgs/notices/kicks or scripts loading. So keep smiling-
# and set this variable as you wish ;), you can either set this to "" to leave it blank.
set pinvlg "\[4x]:"

proc do_invcycle {} {
	global botnick invite_clstat invite_cycle invchk_chans invnotcop pinvlg
	putlog "$pinvlg shutting down channel cycle timer."
	foreach invcltimer [timers] {if {[string match "do_invcycle" [lindex $invcltimer 1]]} {killtimer [lindex $invcltimer 2]}}
	if {$invite_cycle} {
		if {$invite_cycle < 5} {set $invite_cycle 10
		} else {
			foreach clchans $invchk_chans {
				if {[validchan $clchans]} {
					if {[botisop $clchans]} {putlog "$pinvlg cycling channel: $clchans." ; putquick "PART $clchans .:cycling:." ; putquick "JOIN $clchans"
					} else {if {$invnotcop} {putlog "$pinvlg cycling channel: $clchans." ; putquick "PART $clchans .:cycling:." ; putquick "JOIN $clchans"}}
				}
			}
		}
		putlog "$pinvlg activating channel cycle timer."
		timer [expr [rand $invite_cycle] + 1] "do_invcycle"
	} ; return 0
}

proc mgotinvite {nick uhost hand rest} {
	global botnick invite_allow invite_words invite_amsgs pinvlg
	if {[isbotnick $nick] || [matchattr $hand o]} {return 0}
	foreach iallow $invite_allow {
		if {[string match *[string tolower $iallow]* [string tolower $uhost]]} {return 0}
	}
	foreach iwords $invite_words {
		if {[string match *[string tolower $iwords]* [string tolower $rest]]} {
			set inv_reason "$pinvlg Invite Words triggered to $botnick from: $nick."
			set iopmsg "$pinvlg Invite Words to $botnick: [lindex $invite_amsgs [rand [llength $invite_amsgs]]]"
			putlog "$pinvlg Invite Words triggered to $botnick from: $nick."
			doiban $nick $uhost $inv_reason $iopmsg
		}
	} ; return 0
}

proc ngotinvite {from keyword arg} {
	global botnick
	set nick [lindex [split $from !] 0] ; set uhost [lindex [split $from !] 1]
	if {[string match "*.*" $nick]} {return 0}
	if {[string match "#*" [lindex $arg 0]]} {return 0}
	mgotinvite $nick $uhost $uhost $arg ; return 0
}

proc igotinvite {from keyword arg} {
	global botnick invite_allow invite_amsgs pinvlg
	set nick [lindex [split $from !] 0] ; set uhost [lindex [split $from !] 1] ; set hand [lindex [split $from !] 1]
	if {[string match "*.*" $nick]} {return 0}
	if {[isbotnick $nick] || [matchattr $hand o] || [matchattr $hand b]} {return 0}
	foreach iallow $invite_allow {
		if {[string match *[string tolower $iallow]* [string tolower $uhost]]} {return 0}
	}
	set chantarget [lindex $arg 1] ; set chantarget [lindex [split $chantarget :] 1]
	set inv_reason "$pinvlg RAW Invite ($chantarget) to $botnick from: $nick."
	set iopmsg "$pinvlg RAW Invite ($chantarget): [lindex $invite_amsgs [rand [llength $invite_amsgs]]]"
	putlog "$pinvlg RAW Invite ($chantarget) to $botnick from: $nick."
	doiban $nick $uhost $inv_reason $iopmsg ; return 0
}

proc doiban {nick uhost ireason inv_opmsg} {
	global botnick invite_bantm invchk_chans invite_ignore invite_kmsgs inv_banop invnotcop invopnicks pinvlg
	set ibanhost *!*@[lindex [split $uhost @] 1]
	foreach ichan $invchk_chans {
		if {[validchan $ichan]} {
			if {[botisop $ichan]} {
				if {[isop $nick $ichan]} {if {!$inv_banop} {putquick "PRIVMSG $ichan :$inv_opmsg" ; return 0}}
				newignore $ibanhost $botnick $ireason $invite_ignore
				putlog "$pinvlg Placing in Ignore on: $ibanhost for $invite_ignore minute(s)."
				newchanban $ichan $ibanhost $botnick $ireason $invite_bantm
				set members [chanlist $ichan]
				foreach invmember $members {
					set selectedhost [getchanhost $invmember $ichan]
					set invbanhost *!*@[lindex [split $selectedhost @] 1]
					if {$ibanhost == $invbanhost} {
						if {[isop $invmember $ichan]} {putquick "MODE $ichan -o+b $invmember $invmember!*@*"
						} else {if {[isvoice $invmember $ichan]} {putquick "MODE $ichan -v+b $invmember $invmember!*@*"} else {putquick "MODE $ichan +b $invmember!*@*"}
						} ; newchanban $ichan $invmember!*@* $botnick $ireason $invite_bantm ; putkick $ichan $invmember "4$pinvlg $nick: [lindex $invite_kmsgs [rand [llength $invite_kmsgs]]]"
					}
				}
			} else {
				if {$invnotcop} {
					foreach notcinvnick $invopnicks {
						set iopnick [string tolower [lindex [split $notcinvnick ,] 0]] ; set iopchan [string tolower [lindex [split $notcinvnick ,] 1]]
						if {[validchan $iopchan]} {
							if {[onchan $iopnick $iopchan]} {
								if {[isop $iopnick $iopchan]} {
									putquick "NOTICE $iopnick :($iopchan) $ireason, Host: $ibanhost."
									putlog "$pinvlg reporting invites to: $iopnick on channel: $iopchan."
								}
							} else {
								putlog "$pinvlg failed to report invites to: $iopnick on channel: $iopchan."
							}
						}
					}
				} else {
					newignore $ibanhost $botnick $ireason $invite_ignore
					putlog "$pinvlg placing in ignore on: $ibanhost for $invite_ignore minute(s). Reason: $ireason."
				}
			}
		}
	} ; return 0
}

if {[info exist invprotloaded]} {
	if {${invprotloaded}} {
		bind msgm - * mgotinvite
		bind raw - INVITE igotinvite
		bind raw - NOTICE ngotinvite
		do_invcycle
	} else {
		unbind msgm - * mgotinvite
		unbind raw - INVITE igotinvite
		unbind raw - NOTICE ngotinvite
		foreach invcltimer [timers] {
			if {[string match "do_invcycle" [lindex $invcltimer 1]]} {killtimer [lindex $invcltimer 2]}
		}
	}
	putlog "${pinvlg} Protection, Invite Detector + Cycle System. Loaded."}