
# CTCP_floodprot.tcl by Ernst <ernst@studbox.uni-stuttgart.de> [July 25, 1998]
# also works together with other "ctcp" bindings
# (bind ctcp is not stackable, bind raw is)

# Ernst's eggdrop page:  http://www.sodre.net/ernst/eggdrop/

# newfludprot.tcl v1.0 by MrNatural <natural@wolfenet.com> [June 16, 1998]
# fludprot.tcl v1.0 by DeathHand <deadhand@pasha.tnp.com> [June 23, 1997]

# This script would protect your bot from any fludnet ctcp flood. It
# does not allow your bot to answer more than the specified number of
# CTCP requests in the specified number of seconds. 4:60 is default.

# ----------------------------------------------------------------------------

# Answer to maximal 4 CTCP's in 60 seconds

set CTCP_FloodCount 4
set CTCP_FloodTime  60

# Allow these CTCPs to pass through
set CTCP_Allow "ACTION CHAT"

# ----------------------------------------------------------------------------

set CTCP_Count 0
set CTCP_StartTime  0

bind raw - PRIVMSG ctcp:floodprot

proc ctcp:floodprot { from type text } {
  global botnick 

  # Remove the destination and : from the beginning
  set text [string trimleft [string range $text \
                              [string first " " $text] end] ": "]

  if {![string match "\001*\001" $text]} {
    # Not a CTCP, it's something else
    return 0
  }

  global CTCP_Allow

  # Remove the \001 around the text
  set text [string trim $text "\001"]
  # Get the command
  set cmd [string range $text 0 [expr [string first " " $text] - 1]]
  set parms [string range $text [expr [string first " " $text] + 1] end]
  if {$cmd == ""} { set cmd "$text" ; set parms "" }

  if {[lsearch -exact $CTCP_Allow [string toupper $cmd]] >= 0} {
    return 0
  }

  global CTCP_Count CTCP_StartTime
  global CTCP_FloodCount CTCP_FloodTime

  # Return value of 0 accepts ctcp, 1 rejects

  if {[unixtime] - $CTCP_StartTime >= $CTCP_FloodTime} {
    # Case 1: Not in a ctcp watch period: Start one and process the ctcp
    set CTCP_StartTime [unixtime]
    set CTCP_Count 1
    return 0
  } elseif {$CTCP_Count < $CTCP_FloodCount} {
    # Case 2: In a watch period, not over limit: Count ctcp's and process them
    incr CTCP_Count
    return 0
  }
  # Case 3: In a watch period and over limit: Reject the ctcp
  set nick [lindex [split $from "!"] 0]
  set uhost [lindex [split $from "!"] 1]
  putlog "CTCP Exceeded \($text\): $nick \($uhost\) -> not replied"
  return 1
}

putlog "- CTCP floodprot ($CTCP_FloodCount ctcps in $CTCP_FloodTime seconds allowed) by Ernst"
