Code: Select all
namespace eval idleBan {
# Default idle time in minutes
set idle(idle_default) 30
# Delay in seconds between WHOIS commands so the bot won't flood itself off
set idle(whois_delay) 3
# kick reason for beeing idle in the channel
set idle(reason) "Don't be idle in %channel channel please, %duration minutes ban."
# Ban type: 1 - channel ban, 2 - ban in it's internal bans list (newchanban)
set idle(ban_type) 1
# Ban lifetime (if above is set to 2) in minutes. If set to 0 will be permanent.
set idle(ban_lifetime) 60
# Don't edit past this line unless you know what you are doing!
setudef flag idleban
setudef int idletime
bind cron - {?0*} [namespace current]::idle:cron
bind raw - 317 [namespace current]::idle:raw
bind part - * [namespace current]::idle:del
bind sign - * [namespace current]::idle:del
bind nick - * [namespace current]::idle:nick
bind kick - * [namespace current]::idle:kick
proc idle:cron {min hour day month weekday} {
variable idle
foreach channel [channels] {
if {![channel get $channel idleban]} continue
if {![botisop $channel]} continue
set idletime [channel get $channel idletime]
if {!$idletime} {
channel set idletime $idle(default)
}
set channel [string tolower $channel]
foreach member [chanlist $channel] {
if {[isbotnick $member]} continue
if {[isop $member $channel]} continue
if {[isvoice $member $channel]} continue
set handle [nick2hand $member $channel]
if {[matchattr $handle f|f]} continue
set chanidle [getchanidle $member $channel]
if {$chanidle >= $idletime} {
variable check
if {![onchan $member $channel]} return
set pos -1
if {[info exists check($channel)]} {
set pos [idle:pos $member $check($channel)]
}
if {$pos == -1} {
lappend check($channel) $member
}
utimer $idle(whois_delay) [list puthelp "WHOIS $member $member"]
}
}
}
}
proc idle:raw {from key text} {
variable check
if {![info exists check]} return
if {[scan [lrange $text 1 2] {%s%d} member seconds] != 2} return
foreach channel [channels] {
if {![channel get $channel idleban] || ![botisop $channel]} {
idle:action channel $channel
continue
}
set idletime [channel get $channel idletime]
set idle [expr $seconds / 60]
if {$idle < $idletime} {
idle:action member $channel $member
} else {
idle:punish $channel $member $idle
}
}
}
proc idle:del {nick uhost hand channel {text ""}} {
if {[channel get $channel idleban]} {
if {[isbotnick $nick]} {
idle:action channel $channel
} else {
idle:action member $channel $nick
}
}
}
proc idle:nick {nick uhost hand channel newnick} {
if {[isbotnick $nick]} return
if {[channel get $channel idleban]} {
idle:action nick $channel $nick $newnick
}
}
proc idle:kick {nick uhost hand channel vict reason} {
if {[channel get $channel idleban]} {
if {[isbotnick $vict]} {
idle:action channel $channel
} else {
idle:action member $channel $vict
}
}
}
proc idle:action {act channel {member ""} {newnick ""}} {
variable check
set channel [string tolower $channel]
if {![info exists check($channel)]} return
switch -- $act {
default {
return
}
"member" {
set pos [idle:pos $member [join $check($channel)]]
if {$pos != -1} {
set check($channel) [lreplace $check($channel) $pos $pos]
}
}
"channel" {
if {[info exists check($channel)]} {
unset check($channel)
}
}
"nick" {
set pos [idle:pos $member [join $check($channel)]]
if {$pos != -1} {
set check($channel) [lreplace $check($channel) $pos $pos $newnick]
}
}
}
}
proc idle:getChannels {member} {
variable check
set matched ""
foreach channel [channels] {
if {![channel get $channel idleban] || ![botisop $channel]} {
idle:action channel $channel
continue
}
foreach member [join $check($channel)] {
if {![onchan $member $channel]} {
idle:action member $channel $member
}
if {[string equal -nocase $nick $member]} {
lappend matched $channel
}
}
}
return $matched
}
proc idle:punish {channels member idle} {
variable check
foreach channel [join $channels] {
if {![channel get $channel idleban] || ![botisop $channel]} {
idle:action channel $channel
} else {
if {[onchan $member $channel]} {
scan [getchanhost $member $channel] {%*[^@]@%s} host
set mask "*!*@$host"
}
idle:action member $channel $member
idle:stack $channel $member $mask
idle:check $channel
}
}
}
proc idle:stack {channel member mask} {
variable kicks
variable bans
set channel [string tolower $channel]
set pos -1
if {[info exists kicks($channel)]} {
set pos [idle:pos $member $kicks($channel)]
}
if {$pos == -1} {
lappend kicks($channel) $member
} else {
set pos -1
}
if {[info exists bans($channel)]} {
set pos [idle:pos $mask $bans($channel)]
}
if {$pos == -1} {
lappend bans($channel) $mask
}
}
proc idle:pos {needle haystack} {
set count -1
set match 0
foreach element [join $haystack] {
incr count
if {[string equal -nocase $needle $element]} {
set match 1
break
}
}
return "[expr $match>0?$count:"-1"]"
}
proc idle:check {channel} {
variable check
if {[info exists check($channel)]} {
set len [llength [join $check($channel)]]
if {$len} {
utimer 3 [list [namespace current]::idle:action check $channel]
} else {
if {[botisop $channel]} {
variable bans
if {[info exists bans($channel)]} {
idle:stackBans $channel $bans($channel)
}
unset bans($channel)
variable kicks
if {[info exists kicks($channel)]} {
idle:stackKicks $channel $kicks($channel)
}
unset kicks($channel)
}
}
}
}
proc idle:stackBans {channel banlist {max 6}} {
variable idle
set len [llength $banlist]
while {$len > 0} {
if {$len > $max} {
set mode [string repeat "b" $max]
set masks [join [lrange $banlist 0 [expr {$max - 1}]]]
set banlist [lrange $banlist $max end]
incr len -$max
} else {
set mode [string repeat "b" $len]
set masks [join $banlist]
incr len -$len
}
pushmode $channel +$mode $masks
if {$idle(ban_type) == 2} {
idle:newbans $channel $masks
}
}
}
proc idle:newbans {channel banlist} {
variable idle
foreach mask [join $banlist] {
set reason [string map [list "%channel" "$channel" "%duration" "$idle(ban_lifetime)"] $idle(reason)]
newchanban $channel $mask "Anti-Idle" $reason $idle(ban_lifetime)
}
}
proc idle:stackKicks {channel kicklist {max 6}} {
variable idle
set len [llength $kicklist]
while {$len > 0} {
if {$len > $max} {
set stack [join [lrange $kicklist 0 [expr {$max - 1}]]]
set kicklist [lrange $kicklist $max end]
} else {
set stack [join $kicklist]
incr len -$len
}
set reason [string map [list "%channel" "$channel" "%duration" "$idle(ban_lifetime)"] $idle(reason)]
putkick [join $stack ","] $reason
}
}
}
Code: Select all
proc idle:kick {nick uhost hand chan vict reason} {
Code: Select all
proc idle:kick {nick uhost hand channel vict reason} {