Ah, yeah, was playing with that regexp and i use $text as variables and not $arg, and somehow it ended in there as $text as well.
Glad this finally sorted out things.
Code: Select all
## mass-join-protection.tcl v1.6.3 (15Jun2023) by SpiKe^^ ##
# !!!! This version is a DALnet specific script !!!! #
## Version 1.6.3 tries to add script specific netsplit tracking! (by user):
# 1) New setting controls how long to save netsplit users user@host info.
# 2) New setting to exempt users by full nick!user@host mask.
# 3) Script can now be enabled by channel with: .chanset #chan +mjp
# 4) Put the entire script in a new namespace: namespace eval mjp
######################################################
namespace eval mjp { variable mjp ; variable mjpc ; variable mjpq
setudef flag mjp ;# <= Use .chanset #chan +mjp to enable this script by channel.
################### begin settings ###################
# Mass joins, kick-ban on joins:seconds #
set mjp(flood) 4:1
# Exempt all matching users from this script entirely # <- NEW SETTING <-
# - list zero or more exempt masks in the format: nick!user@host #
# - list one exempt mask per file line below. #
set mjp(xmpt-masks) {
} ;# end of: set mjp(xmpt-masks) #
############ kick-ban settings ############
# Mass joins kick-ban reason #
set mjp(reasn) "�-Mass-Joins-�"
# Max number of bans to stack in one mode command #
set mjp(maxb) 6
# Max number of kicks to stack in one kick command #
# NOTE: many networks allow more than one nick to be kicked per command. #
# set this at or below the max for your network.
set mjp(maxk) 4
# Length of time in minutes to ban mass join flooders #
# - set 0 to disable this script removing bans (ex. set mjp(btime) 0) #
set mjp(btime) 0
# After a valid mass join flood, script will continue #
# to kick-ban offenders for an additional 'x' seconds #
set mjp(xpire) 5
# Set the type of ban masks to use #
# 1 = use host/ip specific bans (ex. *!*@some.host.com) #
# 2 = use wide masked host/ip bans (ex. *!*@*.host.com) #
# note: setting 2 requires eggdrop 1.6.20 or newer. #
set mjp(btype) 2
# Don't wide-ban any of these hosts # <- RENAMED SETTING <-
# - Example: set mjp(no-wide-bans) "*.undernet.org"
# Note: this setting only applies to ban type 2 above! #
# Note: set empty to not protect any hosts (ex. set mjp(no-wide-bans) "") #
# Note: space separated if listing more than one host. #
set mjp(no-wide-bans) "*.irccloud.com *.mibbit.com *.clients.kiwiirc.com"
############ channel modes ############
# Set channel mode(s) on flood detected. #
# - set empty to disable setting channel modes (ex. set mjp(mode) "") #
set mjp(mode) "im"
# Remove these channel modes after how many seconds? #
set mjp(mrem) 10
############ netsplit settings ############
# Set the time (in seconds) to store each split users info # <- NEW SETTING <-
set mjp(wait-split) 300
########################################################################
# END OF SETTINGS # Don't edit below unless you know what you're doing #
########################################################################
if {![info exists mjp(issplit-dict)]} { set mjp(issplit-dict) [dict create] }
## thanks to awyeah and nml375 ##
bind raw - QUIT [namespace current]::mjp_bindrawquit
proc mjp_bindrawquit {from key arg} { variable mjp
#putlog "proc [namespace current]::mjp_bindrawquit|| from=($from)|| key=($key)|| arg=($arg)"
set arg [string trimleft [stripcodes bcruag $arg] :]
if {[string equal "Quit:" [string range $arg 0 4]]} { return 0 }
set re {^([[:alnum:][:punct:]]+)[[:space:]]([[:alnum:][:punct:]]+)$}
if {![regexp -- $re $arg _arg s1 s2]} { return 0 }
if {![matchstr "*.dal.net" $s1] || ![matchstr "*.dal.net" $s2]} { return 0 }
#putlog " [namespace current]::mjp_bindrawquit|| s1=($s1)|| s2=($s2)"
set usr [string trim [string tolower [lindex [split $from "!"] 1]] "~"]
if {[dict exists $mjp(issplit-dict) $usr]} {
set mjp(issplit-dict) [dict remove $mjp(issplit-dict) $usr]
}
dict set mjp(issplit-dict) $usr [expr {[unixtime] + $mjp(wait-split)}]
}
########################################################################
bind join - * [namespace current]::mjp_bindjoin
proc mjp_bindjoin {nick uhost hand chan} {
variable mjp ; variable mjpc ; variable mjpq
if {[isbotnick $nick]} { return 0 }
if {![channel get $chan mjp]} { return 0 }
###
if {[matchattr $hand f|f $chan]} { return 0 }
foreach mask $mjp(xmpt-masks) {
if {[matchaddr $mask ${nick}!$uhost]} { return 0 }
}
###
set usr [string trimleft [string tolower $uhost] "~"]
if {[dict exists $mjp(issplit-dict) $usr]} {
set utold [dict get $mjp(issplit-dict) $usr]
if {$utold > [unixtime]} { return 0 } ;# equals usr is netsplit #
# else: equals netsplit info is old #
set mjp(issplit-dict) [dict remove $mjp(issplit-dict) $usr]
}
###
set uhost [string tolower $nick!$uhost]
set chan [string tolower $chan]
set utnow [unixtime]
set target [lindex $mjp(flood) 0]
if {[info exists mjpc($chan)]} {
set uhlist [lassign $mjpc($chan) cnt ut]
set utend [expr {$ut + [lindex $mjp(flood) 1]}]
set expire [expr {$utend + $mjp(xpire)}]
if {$cnt < $target} {
if {$utnow > $utend} { unset mjpc($chan) }
} elseif {$utnow > $expire} { unset mjpc($chan) }
}
if {![info exists mjpc($chan)]} {
set mjpc($chan) [list 1 $utnow $uhost]
return 0
}
incr cnt
if {$cnt <= $target} {
if {[lsearch $uhlist $uhost] == -1} { lappend uhlist $uhost }
if {$cnt < $target} {
set mjpc($chan) [linsert $uhlist 0 $cnt $ut]
} else {
set mjpc($chan) [list $cnt $ut]
if {$mjp(mode) ne "" && [string is digit -strict $mjp(mrem)]} {
putquick "MODE $chan +$mjp(mode)"
utimer $mjp(mrem) [list putquick "MODE $chan -$mjp(mode)"]
}
mjp_dobans $chan $uhlist
}
return 0
}
if {![info exists mjpq($chan)]} {
utimer 2 [list [namespace current]::mjp_bque $chan]
set mjpq($chan) [list $uhost]
} elseif {[lsearch $mjpq($chan) $uhost] == -1} {
lappend mjpq($chan) $uhost
}
if {[llength $mjpq($chan)] >= $mjp(maxb)} {
mjp_dobans $chan $mjpq($chan)
set mjpq($chan) ""
}
return 0
}
########################################################################
proc mjp_dobans {chan uhlist} { variable mjp
if {![botisop $chan]} return
set banList ""
set nickList ""
foreach ele $uhlist {
scan $ele {%[^!]!%[^@]@%s} nick user host
if {$mjp(btype) == 2} { set type 4
foreach ph $mjp(no-wide-bans) {
if {[string match -nocase $ph $host]} {
set type 2 ; break
}
}
set bmask [maskhost $ele $type]
} else { set bmask "*!*@$host" }
if {[lsearch $banList $bmask] == -1} { lappend banList $bmask }
if {[lsearch $nickList $nick] == -1} { lappend nickList $nick }
}
stack_bans $chan $mjp(maxb) $banList
# begin new kick code #
foreach nk $nickList {
if {[onchan $nk $chan]} { lappend nkls $nk } else { continue }
if {[llength $nkls] == $mjp(maxk)} {
putquick "KICK $chan [join $nkls ,] :$mjp(reasn)"
unset nkls
}
}
if {[info exists nkls]} {
putquick "KICK $chan [join $nkls ,] :$mjp(reasn)"
}
# end new kick code #
if {$mjp(btime) > 0} {
set expire [expr {[unixtime] + $mjp(btime)}]
lappend mjp(rmls) [list $expire $chan $banList]
}
}
proc stack_bans {chan max banlist {opt +} } {
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]
set len 0
}
putquick "MODE $chan ${opt}$mode $masks"
}
}
proc mjp_bque {chan} { variable mjpq
if {![info exists mjpq($chan)]} { return }
if {$mjpq($chan) eq ""} { unset mjpq($chan) ; return }
mjp_dobans $chan $mjpq($chan)
unset mjpq($chan)
}
proc mjp_breset {} { variable mjp ; variable mjpc
set utnow [unixtime]
set target [lindex $mjp(flood) 0]
foreach {key val} [array get mjpc] {
lassign $val cnt ut
set utend [expr {$ut + [lindex $mjp(flood) 1]}]
set expire [expr {$utend + $mjp(xpire)}]
if {$cnt < $target} {
if {$utnow > $utend} { unset mjpc($key) }
} elseif {$utnow > $expire} { unset mjpc($key) }
}
if {[info exists mjp(rmls)]} {
while {[llength $mjp(rmls)]} {
set next [lindex $mjp(rmls) 0]
lassign $next expire chan banList
if {$expire > $utnow} { break }
set mjp(rmls) [lreplace $mjp(rmls) 0 0]
if {![info exists rmAra($chan)]} { set rmAra($chan) $banList
} else { set rmAra($chan) [concat $rmAra($chan) $banList] }
}
foreach {key val} [array get rmAra] {
set banList ""
foreach mask $val {
if {![ischanban $mask $key]} { continue }
lappend banList $mask
}
if {$banList eq ""} { continue }
if {![botisop $key]} {
set mjp(rmls) [linsert $mjp(rmls) 0 [list $utnow $key $banList]]
} else { stack_bans $key $mjp(maxb) $banList - }
}
if {![llength $mjp(rmls)]} { unset mjp(rmls) }
}
##
if {[dict size $mjp(issplit-dict)] > 0} { set newdict [dict create]
dict for {usr utold} $mjp(issplit-dict) {
if {$utold > $utnow} { dict set newdict $usr $utold }
}
set mjp(issplit-dict) $newdict
}
##
utimer 30 [list [namespace current]::mjp_breset]
}
if {![info exists mjp(running)]} {
utimer 20 [list [namespace current]::mjp_breset]
set mjp(running) 1
}
##
set mjp(xmpt-masks) [string trim $mjp(xmpt-masks)]
if {$mjp(xmpt-masks) ne ""} {
set mjp(xmpt-masks) [string map {\n " "} $mjp(xmpt-masks)]
set mjp(xmpt-masks) [split [regsub -all -- {\s{2,}} $mjp(xmpt-masks) { }]]
}
##
set mjp(flood) [split $mjp(flood) :]
set mjp(btime) [expr {$mjp(btime) * 60}]
set mjp(no-wide-bans) [split [string trim $mjp(no-wide-bans)]]
if {$mjp(btime)==0 && [info exists mjp(rmls)]} { unset mjp(rmls) }
putlog "Loaded mass-join-protection.tcl v1.6.3 by SpiKe^^"
} ;## end of: namespace eval mjp ##