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.

anti repeat from multi host/ip

Requests for complete scripts or modifications/fixes for scripts you didn't write. Response not guaranteed, and no thread bumping!
Post Reply
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Basically you need to copy stack_ban function but with minus instead of plus, plus something extra to check if any of the bans we push for unban have been lifted already.

Code: Select all

proc stack_unban {chan max blist} {
	if {![botisop $chan]} return
	foreach ban $blist {
		if {![ischanban $ban $chan]} continue
		lappend banlist $ban
	}
	if {![info exists banlist]} return
	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
      }
      putnow "MODE $chan -$mode $masks"
   }
}
and inside rp_dobans after

Code: Select all

stack_ban $chan $mhrp(maxb) $banList 
add this line:

Code: Select all

utimer 600 [list stack_unban $chan $mhrp(maxb) $banList]
PS: I bet you guys heard a million times that args has a special meaning in TCL and should not be used, and guess always wondered why.. Here's why: instead of that ugly

Code: Select all

proc rp_breset {} {
give this a try:

Code: Select all

proc rp_breset args {
Your welcome. 8)
Once the game is over, the king and the pawn go back in the same box.
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

excellent tnx caesar cheers
User avatar
SpiKe^^
Owner
Posts: 831
Joined: Fri May 12, 2006 10:20 pm
Location: Tennessee, USA
Contact:

multi-host-repeat.tcl v1.4 (16May2015) by SpiKe^^

Post by SpiKe^^ »

Final safe version of multi-host-repeat.tcl
This version uses putquick instead of putnow, & no longer requires the bot to be opered.

NEW ADDED: This version adds the ability to have this script remove any bans that it sets for repeat flooders.

Code: Select all

# multi-host-repeat.tcl v1.4 (16May2015) by SpiKe^^, closely based on
# repeat.tcl v1.1 (9Apr1999) by slennox <slenny@ozemail.com.au>
# Special Thanks go out to speechles & caesar

## IMPORTANT: This version of multi-host-repeat.tcl has been made ##
##            safe to run on any eggdrop bot (oper Not required)! ##

## NEW ADDED: This version adds the ability to have this script ##
##            remove any bans that it sets for repeat flooders. ##


# Repeat flood, kick-ban on repeats:seconds #
set mhrp(flood) 3:10

# Repeat flood kick-ban reason #
set mhrp(reasn) "repeat flood"

# Max number of bans to stack in one mode command #
set mhrp(maxb) 6

# Length of time in minutes to ban Repeat flooders #
# - set 0 to disable this script removing bans (ex. set mhrp(btime) 0) #
set mhrp(btime) 10

# After a valid Repeat flood, script will continue to #
# kick-ban offenders for an additional 'x' seconds #
set mhrp(xpire) 10

# Set channel mode(s) on flood detected. #
# - set empty to disable setting channel modes (ex. set mhrp(mode) "") #
set mhrp(mode) "mi"

# Remove these channel modes after how many seconds? #
set mhrp(mrem) 20

# END OF SETTINGS # Don't edit below unless you know what you're doing #

bind pubm - * rp_pubmsg
bind notc - * notc_wrap
bind ctcp - "ACTION" action_wrap

proc action_wrap {n u h d k t} { rp_pubmsg $n $u $h $d $t }

proc notc_wrap {n u h t d} { rp_pubmsg $n $u $h $d $t }

proc rp_pubmsg {nick uhost hand chan text} {
  global mhrp mhrc mhrq
  set uhost [string tolower $nick!$uhost]
  set chan [string tolower $chan]
  set text [string map [list \017 ""] [stripcodes abcgru $text]]
  set text [string tolower $text]
  if {[isbotnick $nick]} { return 0 }
  if {[matchattr $hand f|f $chan]} { return 0 }
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  if {[info exists mhrc($chan:$text)]} {
    set uhlist [lassign $mhrc($chan:$text) cnt ut]
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($chan:$text) }
    } elseif {$utnow > $expire} { unset mhrc($chan:$text) }
  }
  if {![info exists mhrc($chan:$text)]} {
    set mhrc($chan:$text) [list 1 $utnow $uhost]
    return 0
  }
  incr cnt
  if {$cnt <= $target} {
    if {[lsearch $uhlist $uhost] == -1} { lappend uhlist $uhost }
    if {$cnt < $target} {
      set mhrc($chan:$text) [linsert $uhlist 0 $cnt $ut]
    } else {
      set mhrc($chan:$text) [list $cnt $ut]
      if {$mhrp(mode) ne "" && [string is digit -strict $mhrp(mrem)]} {
        putquick "MODE $chan +$mhrp(mode)"
        utimer $mhrp(mrem) [list putquick "MODE $chan -$mhrp(mode)"]
      }
      rp_dobans $chan $uhlist
    }
    return 0
  }
  if {![info exists mhrq($chan)]} {
    utimer 1 [list rp_bque $chan]
    set mhrq($chan) [list $uhost]
  } elseif {[lsearch $mhrq($chan) $uhost] == -1} {
    lappend mhrq($chan) $uhost
  }
  if {[llength $mhrq($chan)] >= $mhrp(maxb)} {
    rp_dobans $chan $mhrq($chan)
    set mhrq($chan) ""
  } elseif {[botisop $chan]} { putquick "KICK $chan $nick :$mhrp(reasn)" }
  return 0
}

proc rp_dobans {chan uhlist} {
  global mhrp
  if {![botisop $chan]} return
  set banList ""
  set nickList ""
  foreach ele $uhlist {
    scan $ele {%[^!]!%[^@]@%s} nick user host
    set bmask "*!*@$host"
    if {[lsearch $banList $bmask] == -1} { lappend banList $bmask }
    if {[lsearch $nickList $nick] == -1} { lappend nickList $nick }
  }
  stack_bans $chan $mhrp(maxb) $banList
  foreach nk $nickList {
    if {[onchan $nk $chan]} { putquick "KICK $chan $nk :$mhrp(reasn)" }
  }


  if {$mhrp(btime) > 0} {
    set expire [expr {[unixtime] + $mhrp(btime)}]
    lappend mhrp(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 rp_bque {chan} {
  global mhrq
  if {![info exists mhrq($chan)]} { return }
  if {$mhrq($chan) eq ""} { unset mhrq($chan) ; return }
  rp_dobans $chan $mhrq($chan)
  unset mhrq($chan)
}

proc rp_breset {} {
  global mhrc mhrp
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  foreach {key val} [array get mhrc] {
    lassign $val cnt ut
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($key) }
    } elseif {$utnow > $expire} { unset mhrc($key) }
  }


  if {[info exists mhrp(rmls)]} {
    while {[llength $mhrp(rmls)]} {
      set next [lindex $mhrp(rmls) 0]
      lassign $next expire chan banList
      if {$expire > $utnow} {  break  }
      set mhrp(rmls) [lreplace $mhrp(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 mhrp(rmls) [linsert $mhrp(rmls) 0 [list $utnow $key $banList]]
      } else {  stack_bans $key $mhrp(maxb) $banList -  }
    }
    if {![llength $mhrp(rmls)]} {  unset mhrp(rmls)  }
  }


  utimer 30 [list rp_breset]
}

if {![info exists rp_running]} {
  utimer 30 [list rp_breset]
  set rp_running 1
}

set mhrp(flood) [split $mhrp(flood) :]
set mhrp(btime) [expr {$mhrp(btime) * 60}]
if {$mhrp(btime)==0 && [info exists mhrp(rmls)]} {  unset mhrp(rmls)  }

putlog "Loaded multi-host-repeat.tcl v1.4 by SpiKe^^"

SpiKe^^

Get BogusTrivia 2.06.4.7 at www.mytclscripts.com
or visit the New Tcl Acrhive at www.tclarchive.org
.
User avatar
SpiKe^^
Owner
Posts: 831
Joined: Fri May 12, 2006 10:20 pm
Location: Tennessee, USA
Contact:

multi-host-repeat.tcl v1.6.1 by SpiKe^^

Post by SpiKe^^ »

This version adds three new settings (see below)

Please test.

Code: Select all

# multi-host-repeat.tcl v1.6.1 (1Mar2016) by SpiKe^^, closely based on
# repeat.tcl v1.1 (9Apr1999) by slennox <slenny@ozemail.com.au>
# Special Thanks go out to speechles & caesar

## NEW ADDED: This version adds three new settings  (see below) ##


# Repeat flood, kick-ban on repeats:seconds #
set mhrp(flood) 3:10

# Repeat flood kick-ban reason #
set mhrp(reasn) "repeat flood"

# Max number of bans to stack in one mode command #
set mhrp(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 mhrp(maxk) 3

# Length of time in minutes to ban Repeat flooders #
# - set 0 to disable this script removing bans (ex. set mhrp(btime) 0) #
set mhrp(btime) 5

# After a valid Repeat flood, script will continue to #
# kick-ban offenders for an additional 'x' seconds #
set mhrp(xpire) 10

# Set the type of ban masks to use #                          <- NEW SETTING <-
#  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 mhrp(btype) 2

# Set protected host(s) that should not be wide masked #      <- NEW SETTING <-
# - Example:  set mhrp(phost) "*.undernet.org"
#  Note: this setting only applies to ban type 2 above! #
#  Note: set empty to not protect any hosts (ex. set mhrp(phost) "") #
#  Note: space separated if listing more than one protected host #
set mhrp(phost) ""

# Set channel mode(s) on flood detected. #
# - set empty to disable setting channel modes (ex. set mhrp(mode) "") #
set mhrp(mode) "mi"

# Remove these channel modes after how many seconds? #
set mhrp(mrem) 20

# END OF SETTINGS # Don't edit below unless you know what you're doing #

bind pubm - * rp_pubmsg
bind notc - * notc_wrap
bind ctcp - "ACTION" action_wrap

proc action_wrap {n u h d k t} { rp_pubmsg $n $u $h $d $t }

proc notc_wrap {n u h t d} { rp_pubmsg $n $u $h $d $t }

proc rp_pubmsg {nick uhost hand chan text} {
  global mhrp mhrc mhrq
  set uhost [string tolower $nick!$uhost]
  set chan [string tolower $chan]
  set text [string map [list \017 ""] [stripcodes abcgru $text]]
  set text [string tolower $text]
  if {[isbotnick $nick]} { return 0 }
  if {[matchattr $hand f|f $chan]} { return 0 }
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  if {[info exists mhrc($chan:$text)]} {
    set uhlist [lassign $mhrc($chan:$text) cnt ut]
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($chan:$text) }
    } elseif {$utnow > $expire} { unset mhrc($chan:$text) }
  }
  if {![info exists mhrc($chan:$text)]} {
    set mhrc($chan:$text) [list 1 $utnow $uhost]
    return 0
  }
  incr cnt
  if {$cnt <= $target} {
    if {[lsearch $uhlist $uhost] == -1} { lappend uhlist $uhost }
    if {$cnt < $target} {
      set mhrc($chan:$text) [linsert $uhlist 0 $cnt $ut]
    } else {
      set mhrc($chan:$text) [list $cnt $ut]
      if {$mhrp(mode) ne "" && [string is digit -strict $mhrp(mrem)]} {
        putquick "MODE $chan +$mhrp(mode)"
        utimer $mhrp(mrem) [list putquick "MODE $chan -$mhrp(mode)"]
      }
      rp_dobans $chan $uhlist
    }
    return 0
  }
  if {![info exists mhrq($chan)]} {
    utimer 1 [list rp_bque $chan]
    set mhrq($chan) [list $uhost]
  } elseif {[lsearch $mhrq($chan) $uhost] == -1} {
    lappend mhrq($chan) $uhost
  }

  if {[llength $mhrq($chan)] >= $mhrp(maxb)} {
    rp_dobans $chan $mhrq($chan)
    set mhrq($chan) ""
  }

  return 0
}

proc rp_dobans {chan uhlist} {
  global mhrp
  if {![botisop $chan]} return
  set banList ""
  set nickList ""
  foreach ele $uhlist {
    scan $ele {%[^!]!%[^@]@%s} nick user host

    if {$mhrp(btype) == 2} {
      set type 4
      foreach ph $mhrp(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 $mhrp(maxb) $banList

  foreach nk $nickList { 
    if {[onchan $nk $chan]} {  lappend nkls $nk  } else { continue }
    if {[llength $nkls] == $mhrp(maxk)} {
      putquick "KICK $chan [join $nkls ,] :$mhrp(reasn)"
      unset nkls
    }
  } 
  if {[info exists nkls]} {
    putquick "KICK $chan [join $nkls ,] :$mhrp(reasn)"
  } 

  if {$mhrp(btime) > 0} {
    set expire [expr {[unixtime] + $mhrp(btime)}]
    lappend mhrp(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 rp_bque {chan} {
  global mhrq
  if {![info exists mhrq($chan)]} { return }
  if {$mhrq($chan) eq ""} { unset mhrq($chan) ; return }
  rp_dobans $chan $mhrq($chan)
  unset mhrq($chan)
}

proc rp_breset {} {
  global mhrc mhrp
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  foreach {key val} [array get mhrc] {
    lassign $val cnt ut
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($key) }
    } elseif {$utnow > $expire} { unset mhrc($key) }
  }
  if {[info exists mhrp(rmls)]} {
    while {[llength $mhrp(rmls)]} {
      set next [lindex $mhrp(rmls) 0]
      lassign $next expire chan banList
      if {$expire > $utnow} {  break  }
      set mhrp(rmls) [lreplace $mhrp(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 mhrp(rmls) [linsert $mhrp(rmls) 0 [list $utnow $key $banList]]
      } else {  stack_bans $key $mhrp(maxb) $banList -  }
    }
    if {![llength $mhrp(rmls)]} {  unset mhrp(rmls)  }
  }
  utimer 30 [list rp_breset]
}

if {![info exists rp_running]} {
  utimer 30 [list rp_breset]
  set rp_running 1
}

set mhrp(flood) [split $mhrp(flood) :]
set mhrp(btime) [expr {$mhrp(btime) * 60}]
set mhrp(phost) [split [string trim $mhrp(phost)]]
if {$mhrp(btime)==0 && [info exists mhrp(rmls)]} {  unset mhrp(rmls)  }

putlog "Loaded multi-host-repeat.tcl v1.6.1 by SpiKe^^"

SpiKe^^

Get BogusTrivia 2.06.4.7 at www.mytclscripts.com
or visit the New Tcl Acrhive at www.tclarchive.org
.
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

tested and it worked fine thnx again SpiKe^^
User avatar
SpiKe^^
Owner
Posts: 831
Joined: Fri May 12, 2006 10:20 pm
Location: Tennessee, USA
Contact:

Post by SpiKe^^ »

NEW ADDED: This version fixes the following two errors: ##
Tcl error [notc_wrap]: expected boolean value but got "illegal channel: botnick"
Tcl error [action_wrap]: expected boolean value but got "illegal channel: botnick"

Code: Select all

# multi-host-repeat.tcl v1.6.2 (17Mar2016) by SpiKe^^, closely based on
# repeat.tcl v1.1 (9Apr1999) by slennox <slenny@ozemail.com.au>
# Special Thanks go out to speechles & caesar

## NEW ADDED: This version fixes the following two errors: ##
# Tcl error [notc_wrap]: expected boolean value but got "illegal channel: botnick"
# Tcl error [action_wrap]: expected boolean value but got "illegal channel: botnick"

# Repeat flood, kick-ban on repeats:seconds #
set mhrp(flood) 3:10

# Repeat flood kick-ban reason #
set mhrp(reasn) "repeat flood"

# Max number of bans to stack in one mode command #
set mhrp(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 mhrp(maxk) 3

# Length of time in minutes to ban Repeat flooders #
# - set 0 to disable this script removing bans (ex. set mhrp(btime) 0) #
set mhrp(btime) 5

# After a valid Repeat flood, script will continue to #
# kick-ban offenders for an additional 'x' seconds #
set mhrp(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 mhrp(btype) 2

# Set protected host(s) that should not be wide masked #
# - Example:  set mhrp(phost) "*.undernet.org"
#  Note: this setting only applies to ban type 2 above! #
#  Note: set empty to not protect any hosts (ex. set mhrp(phost) "") #
#  Note: space separated if listing more than one protected host #
set mhrp(phost) ""

# Set channel mode(s) on flood detected. #
# - set empty to disable setting channel modes (ex. set mhrp(mode) "") #
set mhrp(mode) "mi"

# Remove these channel modes after how many seconds? #
set mhrp(mrem) 20

# END OF SETTINGS # Don't edit below unless you know what you're doing #

bind pubm - * rp_pubmsg
bind notc - * notc_wrap
bind ctcp - "ACTION" action_wrap

proc action_wrap {n u h d k t} {

  if {$d eq $::botnick} {  return 0  }

  rp_pubmsg $n $u $h $d $t
}

proc notc_wrap {n u h t d} {

  if {$d eq $::botnick} {  return 0  }

  rp_pubmsg $n $u $h $d $t
}

proc rp_pubmsg {nick uhost hand chan text} {
  global mhrp mhrc mhrq
  set uhost [string tolower $nick!$uhost]
  set chan [string tolower $chan]
  set text [string map [list \017 ""] [stripcodes abcgru $text]]
  set text [string tolower $text]
  if {[isbotnick $nick]} { return 0 }
  if {[matchattr $hand f|f $chan]} { return 0 }
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  if {[info exists mhrc($chan:$text)]} {
    set uhlist [lassign $mhrc($chan:$text) cnt ut]
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($chan:$text) }
    } elseif {$utnow > $expire} { unset mhrc($chan:$text) }
  }
  if {![info exists mhrc($chan:$text)]} {
    set mhrc($chan:$text) [list 1 $utnow $uhost]
    return 0
  }
  incr cnt
  if {$cnt <= $target} {
    if {[lsearch $uhlist $uhost] == -1} { lappend uhlist $uhost }
    if {$cnt < $target} {
      set mhrc($chan:$text) [linsert $uhlist 0 $cnt $ut]
    } else {
      set mhrc($chan:$text) [list $cnt $ut]
      if {$mhrp(mode) ne "" && [string is digit -strict $mhrp(mrem)]} {
        putquick "MODE $chan +$mhrp(mode)"
        utimer $mhrp(mrem) [list putquick "MODE $chan -$mhrp(mode)"]
      }
      rp_dobans $chan $uhlist
    }
    return 0
  }
  if {![info exists mhrq($chan)]} {
    utimer 1 [list rp_bque $chan]
    set mhrq($chan) [list $uhost]
  } elseif {[lsearch $mhrq($chan) $uhost] == -1} {
    lappend mhrq($chan) $uhost
  }

  if {[llength $mhrq($chan)] >= $mhrp(maxb)} {
    rp_dobans $chan $mhrq($chan)
    set mhrq($chan) ""
  }

  return 0
}

proc rp_dobans {chan uhlist} {
  global mhrp
  if {![botisop $chan]} return
  set banList ""
  set nickList ""
  foreach ele $uhlist {
    scan $ele {%[^!]!%[^@]@%s} nick user host

    if {$mhrp(btype) == 2} {
      set type 4
      foreach ph $mhrp(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 $mhrp(maxb) $banList

  foreach nk $nickList { 
    if {[onchan $nk $chan]} {  lappend nkls $nk  } else { continue }
    if {[llength $nkls] == $mhrp(maxk)} {
      putquick "KICK $chan [join $nkls ,] :$mhrp(reasn)"
      unset nkls
    }
  } 
  if {[info exists nkls]} {
    putquick "KICK $chan [join $nkls ,] :$mhrp(reasn)"
  } 

  if {$mhrp(btime) > 0} {
    set expire [expr {[unixtime] + $mhrp(btime)}]
    lappend mhrp(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 rp_bque {chan} {
  global mhrq
  if {![info exists mhrq($chan)]} { return }
  if {$mhrq($chan) eq ""} { unset mhrq($chan) ; return }
  rp_dobans $chan $mhrq($chan)
  unset mhrq($chan)
}

proc rp_breset {} {
  global mhrc mhrp
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  foreach {key val} [array get mhrc] {
    lassign $val cnt ut
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($key) }
    } elseif {$utnow > $expire} { unset mhrc($key) }
  }
  if {[info exists mhrp(rmls)]} {
    while {[llength $mhrp(rmls)]} {
      set next [lindex $mhrp(rmls) 0]
      lassign $next expire chan banList
      if {$expire > $utnow} {  break  }
      set mhrp(rmls) [lreplace $mhrp(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 mhrp(rmls) [linsert $mhrp(rmls) 0 [list $utnow $key $banList]]
      } else {  stack_bans $key $mhrp(maxb) $banList -  }
    }
    if {![llength $mhrp(rmls)]} {  unset mhrp(rmls)  }
  }
  utimer 30 [list rp_breset]
}

if {![info exists rp_running]} {
  utimer 30 [list rp_breset]
  set rp_running 1
}

set mhrp(flood) [split $mhrp(flood) :]
set mhrp(btime) [expr {$mhrp(btime) * 60}]
set mhrp(phost) [split [string trim $mhrp(phost)]]
if {$mhrp(btime)==0 && [info exists mhrp(rmls)]} {  unset mhrp(rmls)  }

putlog "Loaded multi-host-repeat.tcl v1.6.2 by SpiKe^^"

SpiKe^^

Get BogusTrivia 2.06.4.7 at www.mytclscripts.com
or visit the New Tcl Acrhive at www.tclarchive.org
.
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

thanx for fixing the error SpiKe^^ it took care of it
Tcl error [notc_wrap]: expected boolean value but got "illegal channel: Eggy"
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Code: Select all

if {$d eq $::botnick} {  return 0  } 
Why not:

Code: Select all

if {[isbotnick $d]} return
Thus lower/upper case is ignored.

Also, inside rp_pubmsg function I would add a channel verification above the set uhost or even above global one:

Code: Select all

if {![validchan $chan]} return
And should take care of all issues.
Once the game is over, the king and the pawn go back in the same box.
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

thnx caesar works as well apreciated
User avatar
SpiKe^^
Owner
Posts: 831
Joined: Fri May 12, 2006 10:20 pm
Location: Tennessee, USA
Contact:

multi-host-repeat.tcl v1.6.3 (23Jul2016) by SpiKe^^

Post by SpiKe^^ »

## NEW ADDED: This version adds 4 settings to exempt specific users from this script: ##
# Exempt users by: Eggdrop userfile flags and/or <nick> has ops/voice/halfop

Code: Select all

# multi-host-repeat.tcl v1.6.3 (23Jul2016) by SpiKe^^, closely based on
# repeat.tcl v1.1 (9Apr1999) by slennox <slenny@ozemail.com.au>
# Special Thanks go out to speechles & caesar

## NEW ADDED: This version adds 4 settings to exempt specific users from this script: ##
# Exempt users by: Eggdrop userfile flags and/or nick has ops/voice/halfop

# Repeat flood, kick-ban on repeats:seconds #
set mhrp(flood) 3:10

# Repeat flood kick-ban reason #
set mhrp(reasn) "repeat flood"

# Max number of bans to stack in one mode command #
set mhrp(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 mhrp(maxk) 3

# Length of time in minutes to ban Repeat flooders #
# - set 0 to disable this script removing bans (ex. set mhrp(btime) 0) #
set mhrp(btime) 5

# After a valid Repeat flood, script will continue to #
# kick-ban offenders for an additional 'x' seconds #
set mhrp(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 mhrp(btype) 2

# Set protected host(s) that should not be wide masked #
# - Example:  set mhrp(phost) "*.undernet.org"
#  Note: this setting only applies to ban type 2 above! #
#  Note: set empty to not protect any hosts (ex. set mhrp(phost) "") #
#  Note: space separated if listing more than one protected host #
set mhrp(phost) ""

# Set channel mode(s) on flood detected. #
# - set empty to disable setting channel modes (ex. set mhrp(mode) "") #
set mhrp(mode) "mi"

# Remove these channel modes after how many seconds? #
set mhrp(mrem) 20


# Set user file flags that should exempt from repeat flood monitoring. #
# - set empty to not exempt any user file flags (ex. set mhrp(xflag) "") #
set mhrp(xflag) "fmno|fmo"

# Should +o nicks in the channel (@nick) be exempt from repeat flood monitoring? #
#  0 = No: do not exempt +o nicks #
#  1 = Yes: exempt all opped nicks #
set mhrp(xop) 1

# Should +v nicks in the channel (+nick) be exempt from repeat flood monitoring? #
#  0 = No: do not exempt +v nicks #
#  1 = Yes: exempt all voiced nicks #
set mhrp(xvoice) 0

# Should halfop nicks in the channel be exempt from repeat flood monitoring? #
#  Note: Your network Must support halfop & Eggdrop setup for halfop on your network! #
#  0 = No: do not exempt halfop nicks #
#  1 = Yes: exempt all halfop nicks #
set mhrp(xhalfop) 0



# END OF SETTINGS # Don't edit below unless you know what you're doing #

bind pubm - * rp_pubmsg
bind notc - * notc_wrap
bind ctcp - "ACTION" action_wrap

proc action_wrap {n u h d k t} {

  if {[isbotnick $d]} {  return 0  }

  rp_pubmsg $n $u $h $d $t
}

proc notc_wrap {n u h t d} {

  if {[isbotnick $d]} {  return 0  }

  rp_pubmsg $n $u $h $d $t
}

proc rp_pubmsg {nick uhost hand chan text} {
  global mhrp mhrc mhrq

  if {[isbotnick $nick]} { return 0 }
  if {$mhrp(xflag) ne "" && $hand ne "*"} {
    if {[matchattr $hand $mhrp(xflag) $chan]} { return 0 }
  }

  if {$mhrp(xop)==1 && [isop $nick $chan]} { return 0 }
  if {$mhrp(xvoice)==1 && [isvoice $nick $chan]} { return 0 }
  if {$mhrp(xhalfop)==1 && [ishalfop $nick $chan]} { return 0 }

  set uhost [string tolower $nick!$uhost]
  set chan [string tolower $chan]
  set text [string map [list \017 ""] [stripcodes abcgru $text]]
  set text [string tolower $text]
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  if {[info exists mhrc($chan:$text)]} {
    set uhlist [lassign $mhrc($chan:$text) cnt ut]
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($chan:$text) }
    } elseif {$utnow > $expire} { unset mhrc($chan:$text) }
  }
  if {![info exists mhrc($chan:$text)]} {
    set mhrc($chan:$text) [list 1 $utnow $uhost]
    return 0
  }
  incr cnt
  if {$cnt <= $target} {
    if {[lsearch $uhlist $uhost] == -1} { lappend uhlist $uhost }
    if {$cnt < $target} {
      set mhrc($chan:$text) [linsert $uhlist 0 $cnt $ut]
    } else {
      set mhrc($chan:$text) [list $cnt $ut]
      if {$mhrp(mode) ne "" && [string is digit -strict $mhrp(mrem)]} {
        putquick "MODE $chan +$mhrp(mode)"
        utimer $mhrp(mrem) [list putquick "MODE $chan -$mhrp(mode)"]
      }
      rp_dobans $chan $uhlist
    }
    return 0
  }
  if {![info exists mhrq($chan)]} {
    utimer 1 [list rp_bque $chan]
    set mhrq($chan) [list $uhost]
  } elseif {[lsearch $mhrq($chan) $uhost] == -1} {
    lappend mhrq($chan) $uhost
  }

  if {[llength $mhrq($chan)] >= $mhrp(maxb)} {
    rp_dobans $chan $mhrq($chan)
    set mhrq($chan) ""
  }

  return 0
}

proc rp_dobans {chan uhlist} {
  global mhrp
  if {![botisop $chan]} return
  set banList ""
  set nickList ""
  foreach ele $uhlist {
    scan $ele {%[^!]!%[^@]@%s} nick user host

    if {$mhrp(btype) == 2} {
      set type 4
      foreach ph $mhrp(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 $mhrp(maxb) $banList

  foreach nk $nickList { 
    if {[onchan $nk $chan]} {  lappend nkls $nk  } else { continue }
    if {[llength $nkls] == $mhrp(maxk)} {
      putquick "KICK $chan [join $nkls ,] :$mhrp(reasn)"
      unset nkls
    }
  } 
  if {[info exists nkls]} {
    putquick "KICK $chan [join $nkls ,] :$mhrp(reasn)"
  } 

  if {$mhrp(btime) > 0} {
    set expire [expr {[unixtime] + $mhrp(btime)}]
    lappend mhrp(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 rp_bque {chan} {
  global mhrq
  if {![info exists mhrq($chan)]} { return }
  if {$mhrq($chan) eq ""} { unset mhrq($chan) ; return }
  rp_dobans $chan $mhrq($chan)
  unset mhrq($chan)
}

proc rp_breset {} {
  global mhrc mhrp
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  foreach {key val} [array get mhrc] {
    lassign $val cnt ut
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($key) }
    } elseif {$utnow > $expire} { unset mhrc($key) }
  }
  if {[info exists mhrp(rmls)]} {
    while {[llength $mhrp(rmls)]} {
      set next [lindex $mhrp(rmls) 0]
      lassign $next expire chan banList
      if {$expire > $utnow} {  break  }
      set mhrp(rmls) [lreplace $mhrp(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 mhrp(rmls) [linsert $mhrp(rmls) 0 [list $utnow $key $banList]]
      } else {  stack_bans $key $mhrp(maxb) $banList -  }
    }
    if {![llength $mhrp(rmls)]} {  unset mhrp(rmls)  }
  }
  utimer 30 [list rp_breset]
}

if {![info exists rp_running]} {
  utimer 30 [list rp_breset]
  set rp_running 1
}

set mhrp(flood) [split $mhrp(flood) :]
set mhrp(btime) [expr {$mhrp(btime) * 60}]
set mhrp(phost) [split [string trim $mhrp(phost)]]
if {$mhrp(btime)==0 && [info exists mhrp(rmls)]} {  unset mhrp(rmls)  }

set mhrp(xflag) [string trim $mhrp(xflag)]
if {$mhrp(xflag) eq "-" || $mhrp(xflag) eq "-|-"} {  set mhrp(xflag) ""  }

putlog "Loaded multi-host-repeat.tcl v1.6.3 by SpiKe^^"

SpiKe^^

Get BogusTrivia 2.06.4.7 at www.mytclscripts.com
or visit the New Tcl Acrhive at www.tclarchive.org
.
g
gamble27
Halfop
Posts: 71
Joined: Tue Aug 05, 2008 7:51 am

Post by gamble27 »

can we have the option to off the kicks if we want to, reason being is if the tcl is paired with your other mass join tcl, during floods it creates unnecessary lag on the bot as both tcl are triggered during mass join floods with same message. Both tcl triggers to kick single flooder and if there is a lot of floodbots there is lag that can lead to bot being excess flooded.

Regards
User avatar
SpiKe^^
Owner
Posts: 831
Joined: Fri May 12, 2006 10:20 pm
Location: Tennessee, USA
Contact:

multi-host-repeat.tcl v1.6.4 (1Jan2017)

Post by SpiKe^^ »

gamble27: See if this addresses your request.

Code: Select all

# multi-host-repeat.tcl v1.6.4 (1Jan2017) by SpiKe^^, closely based on
# repeat.tcl v1.1 (9Apr1999) by slennox <slenny@ozemail.com.au>
# Special Thanks go out to speechles & caesar

## NEW ADDED: This version adds the ability to have this script NOT do kicks. ##
# Example:  set mhrp(maxk) 0


# Repeat flood, kick-ban on repeats:seconds #
set mhrp(flood) 3:10

# Repeat flood kick-ban reason #
set mhrp(reasn) "repeat flood"

# Max number of bans to stack in one mode command #
set mhrp(maxb) 6


# Max number of kicks to stack in one kick command #  !NEW!: set this to 0 to disable kicks  #
# NOTE: many networks allow more than one nick to be kicked per command. #
#       set this at or below the max for your network.
set mhrp(maxk) 3


# Length of time in minutes to ban Repeat flooders #
# - set 0 to disable this script removing bans (ex. set mhrp(btime) 0) #
set mhrp(btime) 5

# After a valid Repeat flood, script will continue to #
# kick-ban offenders for an additional 'x' seconds #
set mhrp(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 mhrp(btype) 2

# Set protected host(s) that should not be wide masked #
# - Example:  set mhrp(phost) "*.undernet.org"
#  Note: this setting only applies to ban type 2 above! #
#  Note: set empty to not protect any hosts (ex. set mhrp(phost) "") #
#  Note: space separated if listing more than one protected host #
set mhrp(phost) ""

# Set channel mode(s) on flood detected. #
# - set empty to disable setting channel modes (ex. set mhrp(mode) "") #
set mhrp(mode) "mi"

# Remove these channel modes after how many seconds? #
set mhrp(mrem) 20


# Set user file flags that should exempt from repeat flood monitoring. #
# - set empty to not exempt any user file flags (ex. set mhrp(xflag) "") #
set mhrp(xflag) "fmno|fmo"

# Should +o nicks in the channel (@nick) be exempt from repeat flood monitoring? #
#  0 = No: do not exempt +o nicks #
#  1 = Yes: exempt all opped nicks #
set mhrp(xop) 1

# Should +v nicks in the channel (+nick) be exempt from repeat flood monitoring? #
#  0 = No: do not exempt +v nicks #
#  1 = Yes: exempt all voiced nicks #
set mhrp(xvoice) 0

# Should halfop nicks in the channel be exempt from repeat flood monitoring? #
#  Note: Your network Must support halfop & Eggdrop setup for halfop on your network! #
#  0 = No: do not exempt halfop nicks #
#  1 = Yes: exempt all halfop nicks #
set mhrp(xhalfop) 0



# END OF SETTINGS # Don't edit below unless you know what you're doing #

bind pubm - * rp_pubmsg
bind notc - * notc_wrap
bind ctcp - "ACTION" action_wrap

proc action_wrap {n u h d k t} {

  if {[isbotnick $d]} {  return 0  }

  rp_pubmsg $n $u $h $d $t
}

proc notc_wrap {n u h t d} {

  if {[isbotnick $d]} {  return 0  }

  rp_pubmsg $n $u $h $d $t
}

proc rp_pubmsg {nick uhost hand chan text} {
  global mhrp mhrc mhrq

  if {[isbotnick $nick]} { return 0 }
  if {$mhrp(xflag) ne "" && $hand ne "*"} {
    if {[matchattr $hand $mhrp(xflag) $chan]} { return 0 }
  }

  if {$mhrp(xop)==1 && [isop $nick $chan]} { return 0 }
  if {$mhrp(xvoice)==1 && [isvoice $nick $chan]} { return 0 }
  if {$mhrp(xhalfop)==1 && [ishalfop $nick $chan]} { return 0 }

  set uhost [string tolower $nick!$uhost]
  set chan [string tolower $chan]
  set text [string map [list \017 ""] [stripcodes abcgru $text]]
  set text [string tolower $text]
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  if {[info exists mhrc($chan:$text)]} {
    set uhlist [lassign $mhrc($chan:$text) cnt ut]
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($chan:$text) }
    } elseif {$utnow > $expire} { unset mhrc($chan:$text) }
  }
  if {![info exists mhrc($chan:$text)]} {
    set mhrc($chan:$text) [list 1 $utnow $uhost]
    return 0
  }
  incr cnt
  if {$cnt <= $target} {
    if {[lsearch $uhlist $uhost] == -1} { lappend uhlist $uhost }
    if {$cnt < $target} {
      set mhrc($chan:$text) [linsert $uhlist 0 $cnt $ut]
    } else {
      set mhrc($chan:$text) [list $cnt $ut]
      if {$mhrp(mode) ne "" && [string is digit -strict $mhrp(mrem)]} {
        putquick "MODE $chan +$mhrp(mode)"
        utimer $mhrp(mrem) [list putquick "MODE $chan -$mhrp(mode)"]
      }
      rp_dobans $chan $uhlist
    }
    return 0
  }
  if {![info exists mhrq($chan)]} {
    utimer 1 [list rp_bque $chan]
    set mhrq($chan) [list $uhost]
  } elseif {[lsearch $mhrq($chan) $uhost] == -1} {
    lappend mhrq($chan) $uhost
  }

  if {[llength $mhrq($chan)] >= $mhrp(maxb)} {
    rp_dobans $chan $mhrq($chan)
    set mhrq($chan) ""
  }

  return 0
}

proc rp_dobans {chan uhlist} {
  global mhrp
  if {![botisop $chan]} return
  set banList ""
  set nickList ""
  foreach ele $uhlist {
    scan $ele {%[^!]!%[^@]@%s} nick user host
    if {$mhrp(btype) == 2} {
      set type 4
      foreach ph $mhrp(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 $mhrp(maxb) $banList


  if {$mhrp(maxk) > 0} {


    foreach nk $nickList { 
      if {[onchan $nk $chan]} {  lappend nkls $nk  } else { continue }
      if {[llength $nkls] == $mhrp(maxk)} {
        putquick "KICK $chan [join $nkls ,] :$mhrp(reasn)"
        unset nkls
      }
    } 
    if {[info exists nkls]} {
      putquick "KICK $chan [join $nkls ,] :$mhrp(reasn)"
    } 


  }


  if {$mhrp(btime) > 0} {
    set expire [expr {[unixtime] + $mhrp(btime)}]
    lappend mhrp(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 rp_bque {chan} {
  global mhrq
  if {![info exists mhrq($chan)]} { return }
  if {$mhrq($chan) eq ""} { unset mhrq($chan) ; return }
  rp_dobans $chan $mhrq($chan)
  unset mhrq($chan)
}

proc rp_breset {} {
  global mhrc mhrp
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  foreach {key val} [array get mhrc] {
    lassign $val cnt ut
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($key) }
    } elseif {$utnow > $expire} { unset mhrc($key) }
  }
  if {[info exists mhrp(rmls)]} {
    while {[llength $mhrp(rmls)]} {
      set next [lindex $mhrp(rmls) 0]
      lassign $next expire chan banList
      if {$expire > $utnow} {  break  }
      set mhrp(rmls) [lreplace $mhrp(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 mhrp(rmls) [linsert $mhrp(rmls) 0 [list $utnow $key $banList]]
      } else {  stack_bans $key $mhrp(maxb) $banList -  }
    }
    if {![llength $mhrp(rmls)]} {  unset mhrp(rmls)  }
  }
  utimer 30 [list rp_breset]
}

if {![info exists rp_running]} {
  utimer 30 [list rp_breset]
  set rp_running 1
}

set mhrp(flood) [split $mhrp(flood) :]
set mhrp(btime) [expr {$mhrp(btime) * 60}]
set mhrp(phost) [split [string trim $mhrp(phost)]]
if {$mhrp(btime)==0 && [info exists mhrp(rmls)]} {  unset mhrp(rmls)  }

set mhrp(xflag) [string trim $mhrp(xflag)]
if {$mhrp(xflag) eq "-" || $mhrp(xflag) eq "-|-"} {  set mhrp(xflag) ""  }

putlog "Loaded multi-host-repeat.tcl v1.6.4 by SpiKe^^"

SpiKe^^

Get BogusTrivia 2.06.4.7 at www.mytclscripts.com
or visit the New Tcl Acrhive at www.tclarchive.org
.
User avatar
SpiKe^^
Owner
Posts: 831
Joined: Fri May 12, 2006 10:20 pm
Location: Tennessee, USA
Contact:

multi-host-repeat.tcl v1.6.5 (16Aug2018)

Post by SpiKe^^ »

We have a new updated version of multi-host-repeat.tcl

This version adds several new banmask options and a setting to enable/disable sending by putnow.

Please help test this script simo.

Code: Select all

# multi-host-repeat.tcl v1.6.5 (16Aug2018) by SpiKe^^, closely based on
# repeat.tcl v1.1 (9Apr1999) by slennox <slenny@ozemail.com.au>
# Special Thanks go out to speechles & caesar


##  Advanced multi-host repeat flood detection and protection script.  ##

##  Monitors all text from all channel users for signs of a botnet repeat flood.  ##
##  See Description & Versions @:  http://forum.egghelp.org/viewtopic.php?t=19898 ##


# Repeat flood, kick-ban on repeats:seconds #
set mhrp(flood) 5:10

# Repeat flood kick-ban reason #
set mhrp(reasn) "repeat flood"

# Max number of bans to stack in one mode command #
set mhrp(maxb) 6

# Max number of kicks to stack in one kick command #
# - set 0 to disable this script doing kicks (ex. set mhrp(maxk) 0) #
# NOTE: many networks allow more than one nick to be kicked per command. #
#       set this at or below the max for your network. #
set mhrp(maxk) 3

# Length of time in minutes to ban Repeat flooders #
# - set 0 to disable this script removing bans (ex. set mhrp(btime) 0) #
set mhrp(btime) 5

# After a valid Repeat flood, script will continue to #
# kick-ban offenders for an additional 'x' seconds #
set mhrp(xpire) 10


# Set the type of ban masks to use #                     <<== NEW SETTING OPTIONS <<==
#  0 = use eggdrop default bans (ex. *!*user@*.host.com) #
#  1 = use host/ip specific bans (ex. *!*@some.host.com) #
# Note: settings 2+ require eggdrop 1.6.20 or newer      #
#  2 = use wide masked host/ip bans (ex. *!*@*.host.com) #
#  3 = use extra-wide host bans (domain:  *!*@*.msn.com) #
#  4 = also use extra-wide ipv4 bans (ex.  *!*@68.186.*) #
#  5 = also extra-wide ipv6 bans  (ex.  *!*@2606:df00:*) #
set mhrp(btype) 2


# Set protected host(s) that should not be wide masked #
# - Example:  set mhrp(phost) "*.undernet.org *.irccloud.com"
#  Note: this setting only applies to ban types 2+ above! #
#  Note: set empty to not protect any hosts (ex. set mhrp(phost) "") #
#  Note: space separated if listing more than one protected host #
set mhrp(phost) ""

# Set channel mode(s) on flood detected. #
# - set empty to disable setting channel modes (ex. set mhrp(mode) "") #
set mhrp(mode) "mi"

# Remove these channel modes after how many seconds? #
set mhrp(mrem) 20

# Set user file flags that should be exempt from repeat flood monitoring. #
# - set empty to not exempt any user file flags (ex. set mhrp(xflag) "") #
set mhrp(xflag) "fmno|fmo"

# Should +o nicks in the channel (@nick) be exempt from repeat flood monitoring? #
#  0 = No: do not exempt +o nicks #
#  1 = Yes: exempt all opped nicks #
set mhrp(xop) 1

# Should +v nicks in the channel (+nick) be exempt from repeat flood monitoring? #
#  0 = No: do not exempt +v nicks #
#  1 = Yes: exempt all voiced nicks #
set mhrp(xvoice) 0

# Should halfop nicks in the channel be exempt from repeat flood monitoring? #
#  Note: Your network Must support halfop & Eggdrop setup for halfop on your network! #
#  0 = No: do not exempt halfop nicks #
#  1 = Yes: exempt all halfop nicks #
set mhrp(xhalfop) 0


# Script sends to the server using putnow? #                     <<== NEW SETTING <<==
#  Note: Don't use putnow unless your bot is opered and has no limits! #
#  0 = No: send to the server using putquick #
#  1 = Yes: send to the server using putnow #
set mhrp(pnow) 0



# END OF SETTINGS # Don't edit below unless you know what you're doing #

bind pubm - * rp_pubmsg
bind notc - * notc_wrap
bind ctcp - "ACTION" action_wrap

proc action_wrap {n u h d k t} {
  if {[isbotnick $d]} {  return 0  }
  rp_pubmsg $n $u $h $d $t
}
proc notc_wrap {n u h t d} {
  if {[isbotnick $d]} {  return 0  }
  rp_pubmsg $n $u $h $d $t
}

proc rp_pubmsg {nick uhost hand chan text} {
  global mhrp mhrc mhrq
  if {[isbotnick $nick]} { return 0 }
  if {$mhrp(xflag) ne "" && $hand ne "*"} {
    if {[matchattr $hand $mhrp(xflag) $chan]} { return 0 }
  }
  if {$mhrp(xop)==1 && [isop $nick $chan]} { return 0 }
  if {$mhrp(xvoice)==1 && [isvoice $nick $chan]} { return 0 }
  if {$mhrp(xhalfop)==1 && [ishalfop $nick $chan]} { return 0 }

  set uhost [string tolower $nick!$uhost]
  set chan [string tolower $chan]
  set text [string map [list \017 ""] [stripcodes abcgru $text]]
  set text [string tolower $text]
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  if {[info exists mhrc($chan:$text)]} {
    set uhlist [lassign $mhrc($chan:$text) cnt ut]
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($chan:$text) }
    } elseif {$utnow > $expire} { unset mhrc($chan:$text) }
  }
  if {![info exists mhrc($chan:$text)]} {
    set mhrc($chan:$text) [list 1 $utnow $uhost]
    return 0
  }
  incr cnt
  if {$cnt <= $target} {
    if {[lsearch $uhlist $uhost] == -1} { lappend uhlist $uhost }
    if {$cnt < $target} {
      set mhrc($chan:$text) [linsert $uhlist 0 $cnt $ut]
    } else {
      set mhrc($chan:$text) [list $cnt $ut]
      if {$mhrp(mode) ne "" && [string is digit -strict $mhrp(mrem)]} {

        $mhrp(phow) "MODE $chan +$mhrp(mode)"
        utimer $mhrp(mrem) [list $mhrp(phow) "MODE $chan -$mhrp(mode)"]

      }
      rp_dobans $chan $uhlist
    }
    return 0
  }
  if {![info exists mhrq($chan)]} {
    utimer 1 [list rp_bque $chan]
    set mhrq($chan) [list $uhost]
  } elseif {[lsearch $mhrq($chan) $uhost] == -1} {
    lappend mhrq($chan) $uhost
  }
  if {[llength $mhrq($chan)] >= $mhrp(maxb)} {
    rp_dobans $chan $mhrq($chan)
    set mhrq($chan) ""
  }
  return 0
}

proc rp_dobans {chan uhlist} {
  global mhrp
  if {![botisop $chan]} return
  set banList ""  ;  set nickList ""
  foreach ele $uhlist {
    scan $ele {%[^!]!%[^@]@%s} nick user host

    if {$mhrp(btype)==0} {  set bmask [maskhost $ele]

    } elseif {$mhrp(btype)>1} {  set type 4
      foreach ph $mhrp(phost) {
        if {[string match -nocase $ph $host]} {
          set type 2  ;  break
        }
      }
      set bmask [maskhost $ele $type]

      if {$mhrp(btype)>2 && $type==4} {
        set mhost [string range $bmask 4 end]
        if {[string index $mhost 0] eq "*"} {
          if {[llength [set mhls [split $mhost "."]]]>3} {
            set bmask "*!*@*.[lindex $mhls end-1].[lindex $mhls end]"
          }
        } elseif {[string index $mhost end-1] eq "."} {
          if {$mhrp(btype)>3} {  set mhls [split $mhost "."]
            set bmask "*!*@[lindex $mhls 0].[lindex $mhls 1].*"
          }
        } elseif {$mhrp(btype)>4} {  set mhls [split $mhost ":"]
          set bmask "*!*@[lindex $mhls 0]:[lindex $mhls 1]:*"
        }
      }

    } else {  set bmask "*!*@$host"  }

    if {[lsearch $banList $bmask] == -1} { lappend banList $bmask }
    if {[lsearch $nickList $nick] == -1} { lappend nickList $nick }
  }
  stack_bans $chan $mhrp(maxb) $banList
  if {$mhrp(maxk) > 0} {
    foreach nk $nickList { 
      if {[onchan $nk $chan]} {  lappend nkls $nk  } else { continue }
      if {[llength $nkls] == $mhrp(maxk)} {

        $mhrp(phow) "KICK $chan [join $nkls ,] :$mhrp(reasn)"

        unset nkls
      }
    } 
    if {[info exists nkls]} {

      $mhrp(phow) "KICK $chan [join $nkls ,] :$mhrp(reasn)"

    } 
  }
  if {$mhrp(btime) > 0} {
    set expire [expr {[unixtime] + $mhrp(btime)}]
    lappend mhrp(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
    }

    $mhrp(phow) "MODE $chan ${opt}$mode $masks"

  }
}

proc rp_bque {chan} {
  global mhrq
  if {![info exists mhrq($chan)]} { return }
  if {$mhrq($chan) eq ""} { unset mhrq($chan) ; return }
  rp_dobans $chan $mhrq($chan)
  unset mhrq($chan)
}

proc rp_breset {} {
  global mhrc mhrp
  set utnow [unixtime]
  set target [lindex $mhrp(flood) 0]
  foreach {key val} [array get mhrc] {
    lassign $val cnt ut
    set utend [expr {$ut + [lindex $mhrp(flood) 1]}]
    set expire [expr {$utend + $mhrp(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhrc($key) }
    } elseif {$utnow > $expire} { unset mhrc($key) }
  }
  if {[info exists mhrp(rmls)]} {
    while {[llength $mhrp(rmls)]} {
      set next [lindex $mhrp(rmls) 0]
      lassign $next expire chan banList
      if {$expire > $utnow} {  break  }
      set mhrp(rmls) [lreplace $mhrp(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 mhrp(rmls) [linsert $mhrp(rmls) 0 [list $utnow $key $banList]]
      } else {  stack_bans $key $mhrp(maxb) $banList -  }
    }
    if {![llength $mhrp(rmls)]} {  unset mhrp(rmls)  }
  }
  utimer 30 [list rp_breset]
}

if {![info exists rp_running]} {
  utimer 30 [list rp_breset]
  set rp_running 1
}


if {$numversion<"1062000" && $mhrp(btype)>1} {  set mhrp(btype) 1  }

set mhrp(phow) "putquick"
if {$mhrp(pnow)==1} {  set mhrp(phow) "putnow"  }


set mhrp(flood) [split $mhrp(flood) :]
set mhrp(btime) [expr {$mhrp(btime) * 60}]
set mhrp(phost) [split [string trim $mhrp(phost)]]
if {$mhrp(btime)==0 && [info exists mhrp(rmls)]} {  unset mhrp(rmls)  }

set mhrp(xflag) [string trim $mhrp(xflag)]
if {$mhrp(xflag) eq "-" || $mhrp(xflag) eq "-|-"} {  set mhrp(xflag) ""  }

putlog "Loaded multi-host-repeat.tcl v1.6.5 by SpiKe^^"

SpiKe^^

Get BogusTrivia 2.06.4.7 at www.mytclscripts.com
or visit the New Tcl Acrhive at www.tclarchive.org
.
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

tested seems to work fine nice work SpiKe^^

was curious about : set mhrp(phost) ""
should exempted hosts be seperated by a , or space ?
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

space separated if listing more than one protected host
says in the code he posted. :roll:
Once the game is over, the king and the pawn go back in the same box.
Post Reply