No, this script does not try to "exempt the netsplit users rejoining channel"
I'm really not sure what would be the best plan to do such exempting.
I could use some advice on ways to pull this off, any suggestions would be much appreciated.
What's the logic behind a script to stop the join floods? Let's say 30 bots join and at the same time some innocent user. How do you differentiate between them? Or you simply just ban them all?
Won't a script that's setting an "active" channel limit put a foot on the neck of a botnet trying to join the channel and thus limit the damage?
Once the game is over, the king and the pawn go back in the same box.
Oh so true Caesar, on both of those points.
I would never run a mass join flood script on any of my channels.
There are other better ways of handling such problems.
I am just trying to build this script for the multiple requests...
gamble27: After more research, no further coding is required to "exempt the netsplit users rejoining channel".
Eggdrop already differentiates between joins and netsplit rejoins.
The amount of time Eggdrop waits for a user to netsplit rejoin is controlled by the Eggdrop config setting: wait-split
When using this script, or any join flood script, be sure to set wait-split to 600 seconds or larger than the longest split on your network.
most mass joins are done with botnets and depending on traffic one can adjust the config setting for it or/and make use of some sort of chanlimit and since bans are temporare innocent ones can rejoin anyway after bantime
if there are other ways of keeping botnets out im curious to know as i tested it in many configurations
regarding netsplit since netsplit shows in quit messages of the unlinked server one could use that to store with a timer and halt this script ( on detect in the quits script )
this is how i would do in an msl script i lack experience in tcl to convert
I have a new setting and the new supporting code that needs testing please...
# Max number of kicks to stack in one kick command # <- NEW SETTING <-
# NOTE: many networks allow more than one nick to be kicked per command. #
# set this at or below the max for your network.
## mass-join-protection.tcl v1.6.1 (29Feb2016) by SpiKe^^ ##
# Mass joins, kick-ban on joins:seconds #
set mjp(flood) 5:2
# Mass joins kick-ban reason #
set mjp(reasn) "Mass Join Flood!"
# Max number of bans to stack in one mode command #
set mjp(maxb) 6
# Max number of kicks to stack in one kick command # <- NEW SETTING <-
# 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) 3
# 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) 10
# After a valid mass join flood, script will continue #
# to kick-ban offenders for an additional 'x' seconds #
set mjp(xpire) 10
# 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
# Set protected host(s) that should not be wide masked #
# - Example: set mjp(phost) "*.undernet.org"
# Note: this setting only applies to ban type 2 above! #
# Note: set empty to not protect any hosts (ex. set mjp(phost) "") #
# Note: space separated if listing more than one protected host #
set mjp(phost) ""
# 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) 20
# END OF SETTINGS # Don't edit below unless you know what you're doing #
bind join - * mjp_bindjoin
proc mjp_bindjoin {nick uhost hand chan} {
global mjp mjpc mjpq
if {[isbotnick $nick]} { return 0 }
if {[matchattr $hand f|f $chan]} { return 0 }
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 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} {
global 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(phost) {
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} {
global 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 {} {
global mjpc mjp
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) }
}
utimer 30 [list mjp_breset]
}
if {![info exists mjp_running]} {
utimer 20 [list mjp_breset]
set mjp_running 1
}
set mjp(flood) [split $mjp(flood) :]
set mjp(btime) [expr {$mjp(btime) * 60}]
set mjp(phost) [split [string trim $mjp(phost)]]
if {$mjp(btime)==0 && [info exists mjp(rmls)]} { unset mjp(rmls) }
putlog "Loaded mass-join-protection.tcl v1.6.1 by SpiKe^^"
tested it on testnet and it works like a charm insanely fast, once again excellent release SpiKe^^ thnx for the workz im sure it will benefit many if they are aware of it keep up the works
i found this tcl from user for banmasks i was wondering if it could be integrated (and if so how) to achieve the banmask for the anti massjoin tcl to be in the form of :