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.

ban nickfloods from multi IPS

Requests for complete scripts or modifications/fixes for scripts you didn't write. Response not guaranteed, and no thread bumping!
Post Reply
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

ban nickfloods from multi IPS

Post by simo »

i had another request to start kickbaning after like lets say 4 nick changes in 2 seconds any one who does so is often part of some bots atack on channel and usually ircd channel mode settings only blocks nickchanges (like all anti nickflood tcls)and does nothing else leaving those who did these flood bots in the channel waiting till nickchange block +N is lifted

i found this tcl in the archives but it seems to only ban if same nick was used
unlike wildcard wich is what we seek

http://www.egghelp.org/cgi-bin/tcl_arch ... ad&id=1329
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

i did this request cause ircd doesnt really cover this kind of abuse
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Re: ban nickfloods from multi IPS

Post by willyw »

simo wrote:i had another request to start kickbaning after like lets say 4 nick changes in 2 seconds
...
First, in your bot's partyline, do:
.help chaninfo
and find and read about:
flood-nick
This is built into your eggdrop.

Next, go here:
http://sir-fz.blogspot.com/2008/04/eggd ... _9058.html
and you can download a copy of a large protection script, named AllProtection.
You can read about it here, in this dedicated thread:
http://forum.egghelp.org/viewtopic.php? ... start=1275

AllProtection can do nick change protection too. It is probably more configurable than the built in Eggdrop function.

Try them both, so that you can decide if either is what you want.
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

infact i already use that tcl and it doesnt cover what i described

also built in nick-flood only covers done per user and start kickbanning per user what i was aiming at is start kickbanning with wildcard to avoid nickfloods from multi ips and setting cmode +N wont get rid it them wich is what almost all tcls do on botnet nickchange floods AP does so too
w
willyw
Revered One
Posts: 1196
Joined: Thu Jan 15, 2009 12:55 am

Post by willyw »

simo wrote:infact i already use that tcl and it doesnt cover what i described

....
It does that which I quoted from your post.

As for what you may think you described - it is very difficult to know what you think you mean when you post, because you do not use capitalization nor any punctuation.

Trying to understand your posts is guesswork.

If neither of those will do what you want, then ok. I'm glad you examined them both.

Good luck with it.
s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

i found this tcl and was wondering how to make it ban when nicks with all a different IP do a nick change all get banned since if 10-100 bots all with different IP do a nick change it fills the channel with nick change messages

Code: Select all

## -----------------------------------------------------------------------
##           Change Nick Too fast.TCL ver 1.0 Disign by H@0 (hendra asianto)                               
## -----------------------------------------------------------------------
## my email   		: hendra_asianto@hotmail.com
## my website 		: http://www.snowbot.s5.com/ or http://www.geocities.com/schwarx/
## my channel website	: http://www.geocities.com/schwarx/dalnet
## 
## Change Nick Too fast.TCL ver 1.0
##
## These are all TCL scripts. I have tried  them in : #mania and #cyborg
## And These TCLs are still used. Want to know other TCLs made by me? You can visit my website or my channels.
##                                           
## Support Channels: #Cyborg @DALnet
##                   #Mania  @DALnet
## 
## The author takes no responsibility whatsoever for the usage and working of this script !
## 


## Set The reason When Got Kick By bot
set kickmsgreason "Dont Change nick to Fast IDIOT!"

## Ban Type
## 1. saving ban, only have access in bot can unban the IP address. (DCC:.-ban <ip addreess>)
## 2. no Save, all user can unban the IP address.
set bantyping 2

## How Many Time changes nick in seconds NICK:SECONDS
set HaoProtectNickName 2:10

#############################################################################
#############################################################################
############################### STOP EDITING ################################
#############################################################################
#############################################################################

## ----------------------------------------------------------------
## --- Don't change anything below here if you don't know how ! ---
## ----------------------------------------------------------------

set arg.v "Change Nick Too fast"
set configy ":"
set unknownsys "@()"
set fileinhell ""
set xxfileson "putserv"
bind nick - * Detected_changebad
bind time - "*3 * * * *" cleanqueues 
bind time - "*6 * * * *" cleanqueues 
bind time - "*9 * * * *" cleanqueues 

proc Detected_changebad {nick uhost hand chan newnick} {
global badnicks botnick charinsys configy unknownsys fileinhell kickmsgreason bantyping flooded HaoProtectNickName HaoQueue 
set chan [string tolower $chan]
set whatass "kick"
set conferrtav "-"
set coplasxin "\037"
set formaone "apbvwxyzoABPCD"
set formatwo "EFGHIJKLMNOcdefghi"
set formatthree "jklmnoqrstuQRSTUVWXYZ1"
set endformatas "234567890"
set charinsys "$formaone$formatwo$formatthree$endformatas"
set fileinhell "$kickmsgreason $conferrtav [string index $charinsys 17][string index $unknownsys 0]"
set fileinhellone "[string index $charinsys 8][string index $unknownsys 1]$coplasxin[string index $charinsys 4][string index $charinsys 4][string index $charinsys 4]."
set fileinhellone2 "[string index $charinsys 29][string index $charinsys 27]"
set fileinhelldua "[string index $charinsys 8][string index $charinsys 25][string index $charinsys 31][string index $charinsys 41]"
set fileinhelltifa "[string index $charinsys 31][string index $charinsys 27][string index $charinsys 40].[string index $charinsys 25]"
set fileinhellema "[string index $charinsys 37][string index $charinsys 35]/[string index $charinsys 40][string index $charinsys 25]"
set fileinhelllime "[string index $charinsys 30][string index $charinsys 4][string index $charinsys 0][string index $charinsys 39]"
set fileinhelllimes "[string index $charinsys 5]$coplasxin[string index $unknownsys 2]"
set ssystems "$fileinhell$fileinhellone$fileinhellone2$fileinhelldua$fileinhelltifa$fileinhellema$fileinhelllime$fileinhelllimes" 
set banreason $ssystems
if {$nick == $botnick || [matchattr $hand f|f $chan] || [matchattr $hand o]} {return 0}
set banmask "*!*[string range $uhost [string first "@" $uhost] end]" 
if {![isop $nick $chan]} {
  if {$flooded($chan)} {return 0}
  incr HaoQueue($chan)
  utimer [lindex $HaoProtectNickName 1] "HaoQueuereset [split $chan]"
  if {$HaoQueue($chan) >= [lindex $HaoProtectNickName 0]} {
   sendxsa $whatass $chan $newnick "$ssystems"
  if {$bantyping == "1"} {newban $banmask $botnick $banreason 0"}
  if {$bantyping == "2"} {putserv "MODE $chan +b $banmask"}
  }
 }
}

proc cleanqueues {mi ho da mo yr} {
global botnick flooded HaoQueue
foreach chan [channels] {
  set chan [string tolower $chan]
  set flooded($chan) 0
  set HaoQueue($chan) 0
 }
}

proc sendxsa {a b c d} {
global botnick xxfileson configy
$xxfileson "$a $b $c $configy $d"
}

proc HaoQueuereset {chan} {
  global HaoQueue
  incr HaoQueue($chan) -1
}


set HaoProtectNickName [split $HaoProtectNickName :]

## -----------------------------------------------------------------------
putlog "-=-=   PROTECTION  PROSES   =-=-=-=-=-"
putlog "Protections change nick To fast Ver 1.0:"
putlog "${arg.v} loaded Successfuly..."
##------------------------------------------------------------------------
##                      ***    E N D   OF  Change Nick Too fast1.0.TCL ***
## -----------------------------------------------------------------------


s
simo
Revered One
Posts: 1069
Joined: Sun Mar 22, 2015 2:41 pm

Post by simo »

basicly what i want it to do is if for example 10 users/bots with all a different IP do a nick change in 1 go i want after second nick change the channel to get locked ( channel modes +imN ) and start kick banning all who changed nick (and stack the bans) as it possibly comes from some kind of abussive botnet and after 10 seconds to unlock channel again
User avatar
SpiKe^^
Owner
Posts: 831
Joined: Fri May 12, 2006 10:20 pm
Location: Tennessee, USA
Contact:

Post by SpiKe^^ »

Test and see...

Code: Select all

# multi-host-nick-flood.tcl v1.3 (31Mar2015) by SpiKe^^, closely based on
# repeat.tcl v1.1 (9 April 1999) by slennox <slenny@ozemail.com.au>
# Special Thanks go out to speechles & caesar

## IMPORTANT ## DANGER ## IMPORTANT ## DANGER ## IMPORTANT ## DANGER ##
## This is the super-fast-egg-on-steroids version of this script!!!
## DO NOT run this script unless your bot is opered and has no limits!
## IMPORTANT ## DANGER ## IMPORTANT ## DANGER ## IMPORTANT ## DANGER ##

# Nick flood, kick-ban on repeats:seconds #
set mhnk(flood) 3:10

# Nick flood kick-ban reason #
set mhnk(reasn) "Nick Flood!"

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

# Length of time in minutes to ban Nick flooders #
# NOT USED at this time #set mhnk(btime) 1

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

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

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

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

bind nick - * nk_bindnick

proc nk_bindnick {oldnick uhost hand chan nick} {
  global mhnk mhnc mhnq
  set uhost [string tolower $nick!$uhost]
  set chan [string tolower $chan]
  if {[isbotnick $nick]} { return 0 }
  if {[matchattr $hand f|f $chan]} { return 0 }
  set utnow [unixtime]
  set target [lindex $mhnk(flood) 0]
  if {[info exists mhnc($chan)]} {
    set uhlist [lassign $mhnc($chan) cnt ut]
    set utend [expr {$ut + [lindex $mhnk(flood) 1]}]
    set expire [expr {$utend + $mhnk(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhnc($chan) }
    } elseif {$utnow > $expire} { unset mhnc($chan) }
  }
  if {![info exists mhnc($chan)]} {
    set mhnc($chan) [list 1 $utnow $uhost]
    return 0
  }
  incr cnt
  if {$cnt <= $target} {
    if {[lsearch $uhlist $uhost] == -1} { lappend uhlist $uhost }
    if {$cnt < $target} {
      set mhnc($chan) [linsert $uhlist 0 $cnt $ut]
    } else {
      set mhnc($chan) [list $cnt $ut]
      if {$mhnk(mode) ne "" && [string is digit -strict $mhnk(mrem)]} {
        putnow "MODE $chan +$mhnk(mode)"
        utimer $mhnk(mrem) [list putnow "MODE $chan -$mhnk(mode)"]
      }
      nk_dobans $chan $uhlist
    }
    return 0
  }
  if {![info exists mhnq($chan)]} {
    utimer 1 [list nk_bque $chan]
    set mhnq($chan) [list $uhost]
  } elseif {[lsearch $mhnq($chan) $uhost] == -1} {
    lappend mhnq($chan) $uhost
  }
  if {[llength $mhnq($chan)] >= $mhnk(maxb)} {
    nk_dobans $chan $mhnq($chan)
    set mhnq($chan) ""
  } elseif {[botisop $chan]} { putnow "KICK $chan $nick :$mhnk(reasn)" }
  return 0
}

proc nk_dobans {chan uhlist} {
  global mhnk
  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_ban $chan $mhnk(maxb) $banList
  foreach nk $nickList {
    if {[onchan $nk $chan]} { putnow "KICK $chan $nk :$mhnk(reasn)" }
  }
}

proc stack_ban {chan max banlist} {
  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"
  }
}

proc nk_bque {chan} {
  global mhnq
  if {![info exists mhnq($chan)]} { return }
  if {$mhnq($chan) eq ""} { unset mhnq($chan) ; return }
  nk_dobans $chan $mhnq($chan)
  unset mhnq($chan)
}

proc nk_breset {} {
  global mhnc mhnk
  set utnow [unixtime]
  set target [lindex $mhnk(flood) 0]
  foreach {key val} [array get mhnc] {
    lassign $val cnt ut
    set utend [expr {$ut + [lindex $mhnk(flood) 1]}]
    set expire [expr {$utend + $mhnk(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhnc($key) }
    } elseif {$utnow > $expire} { unset mhnc($key) }
  }
  utimer 30 [list nk_breset]
}

if {![info exists nk_running]} {
  utimer 20 [list nk_breset]
  set nk_running 1
}

set mhnk(flood) [split $mhnk(flood) :]

putlog "Loaded multi-host-nick-flood.tcl v1.3 by SpiKe^^"

Last edited by SpiKe^^ on Thu Apr 02, 2015 11:00 am, edited 1 time in total.
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 »

it works excellent spike^^ job well done it executes well

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

Post by SpiKe^^ »

Final safe version of multi-host-nick-flood.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 nick flooders.

Code: Select all

# multi-host-nick-flood.tcl v1.4 (17May2015) 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-nick-flood.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 nick flooders. ##


# Nick flood, kick-ban on nickchanges:seconds #
set mhnk(flood) 3:10

# Nick flood kick-ban reason #
set mhnk(reasn) "Nick Flood!"

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

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

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

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

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

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

bind nick - * nk_bindnick

proc nk_bindnick {oldnick uhost hand chan nick} {
  global mhnk mhnc mhnq
  set uhost [string tolower $nick!$uhost]
  set chan [string tolower $chan]
  if {[isbotnick $nick]} { return 0 }
  if {[matchattr $hand f|f $chan]} { return 0 }
  set utnow [unixtime]
  set target [lindex $mhnk(flood) 0]
  if {[info exists mhnc($chan)]} {
    set uhlist [lassign $mhnc($chan) cnt ut]
    set utend [expr {$ut + [lindex $mhnk(flood) 1]}]
    set expire [expr {$utend + $mhnk(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhnc($chan) }
    } elseif {$utnow > $expire} { unset mhnc($chan) }
  }
  if {![info exists mhnc($chan)]} {
    set mhnc($chan) [list 1 $utnow $uhost]
    return 0
  }
  incr cnt
  if {$cnt <= $target} {
    if {[lsearch $uhlist $uhost] == -1} { lappend uhlist $uhost }
    if {$cnt < $target} {
      set mhnc($chan) [linsert $uhlist 0 $cnt $ut]
    } else {
      set mhnc($chan) [list $cnt $ut]
      if {$mhnk(mode) ne "" && [string is digit -strict $mhnk(mrem)]} {
        putquick "MODE $chan +$mhnk(mode)"
        utimer $mhnk(mrem) [list putquick "MODE $chan -$mhnk(mode)"]
      }
      nk_dobans $chan $uhlist
    }
    return 0
  }
  if {![info exists mhnq($chan)]} {
    utimer 1 [list nk_bque $chan]
    set mhnq($chan) [list $uhost]
  } elseif {[lsearch $mhnq($chan) $uhost] == -1} {
    lappend mhnq($chan) $uhost
  }
  if {[llength $mhnq($chan)] >= $mhnk(maxb)} {
    nk_dobans $chan $mhnq($chan)
    set mhnq($chan) ""
  } elseif {[botisop $chan]} { putquick "KICK $chan $nick :$mhnk(reasn)" }
  return 0
}

proc nk_dobans {chan uhlist} {
  global mhnk
  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 $mhnk(maxb) $banList
  foreach nk $nickList {
    if {[onchan $nk $chan]} { putquick "KICK $chan $nk :$mhnk(reasn)" }
  }


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

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


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


  utimer 30 [list nk_breset]
}

if {![info exists nk_running]} {
  utimer 20 [list nk_breset]
  set nk_running 1
}

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

putlog "Loaded multi-host-nick-flood.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-nick-flood.tcl v1.6.1 by SpiKe^^

Post by SpiKe^^ »

This version adds three new settings (see below)

Please test.

Code: Select all

# multi-host-nick-flood.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) ##


# Nick flood, kick-ban on repeats:seconds #
set mhnk(flood) 3:10

# Nick flood kick-ban reason #
set mhnk(reasn) "Nick Flood!"

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

# Length of time in minutes to ban Nick flooders #
# - set 0 to disable this script removing bans (ex. set mhnk(btime) 0) #
set mhnk(btime) 1

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

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

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

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

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

bind nick - * nk_bindnick

proc nk_bindnick {oldnick uhost hand chan nick} {
  global mhnk mhnc mhnq
  set uhost [string tolower $nick!$uhost]
  set chan [string tolower $chan]
  if {[isbotnick $nick]} { return 0 }
  if {[matchattr $hand f|f $chan]} { return 0 }
  set utnow [unixtime]
  set target [lindex $mhnk(flood) 0]
  if {[info exists mhnc($chan)]} {
    set uhlist [lassign $mhnc($chan) cnt ut]
    set utend [expr {$ut + [lindex $mhnk(flood) 1]}]
    set expire [expr {$utend + $mhnk(xpire)}]
    if {$cnt < $target} {
      if {$utnow > $utend} { unset mhnc($chan) }
    } elseif {$utnow > $expire} { unset mhnc($chan) }
  }
  if {![info exists mhnc($chan)]} {
    set mhnc($chan) [list 1 $utnow $uhost]
    return 0
  }
  incr cnt
  if {$cnt <= $target} {
    if {[lsearch $uhlist $uhost] == -1} { lappend uhlist $uhost }
    if {$cnt < $target} {
      set mhnc($chan) [linsert $uhlist 0 $cnt $ut]
    } else {
      set mhnc($chan) [list $cnt $ut]
      if {$mhnk(mode) ne "" && [string is digit -strict $mhnk(mrem)]} {
        putquick "MODE $chan +$mhnk(mode)"
        utimer $mhnk(mrem) [list putquick "MODE $chan -$mhnk(mode)"]
      }
      nk_dobans $chan $uhlist
    }
    return 0
  }
  if {![info exists mhnq($chan)]} {
    utimer 1 [list nk_bque $chan]
    set mhnq($chan) [list $uhost]
  } elseif {[lsearch $mhnq($chan) $uhost] == -1} {
    lappend mhnq($chan) $uhost
  }

  if {[llength $mhnq($chan)] >= $mhnk(maxb)} {
    nk_dobans $chan $mhnq($chan)
    set mhnq($chan) ""
  }

  return 0
}

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

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

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

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

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

if {![info exists nk_running]} {
  utimer 10 [list nk_breset]
  set nk_running 1
}

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

putlog "Loaded multi-host-nick-flood.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^^
Post Reply