## ¤ dronecheck.tcl
# version 1.0
# author: caesar
# e-mail: <cezarica01 [at] yahoo [dot] com>
# IRC: #eggdrop @ Undernet.org

##
# ¤ Description:
#   Will send a private message upon join to check either or not that person is in fact a drone not a real person.

##
# ¤ Available commands:
#    Where  Flag Command   Description
#    -----  ---- -------   -----------
#     PUB :  N/A
#     MSG :  N/A
#     DCC :  n|n .chanset   Use .chanset to set what protections to active for the particular channel or not.
#                           Example: .chanset #mychan +dronecheck
#                                    .chanset #otherchan -dronecheck

##
# ¤ Notes:
#   This script was tested to work properly on eggdrop 1.6.17 or greater. Please upgrade
# your eggdrop or remove/unload the script.
#
#   Some sort of feedback will be appreciated!

##
# ¤ Custom channel flags:
#    Flag:         Description:
#    -----         ------------
#    +dronecheck   Will send that on join message.
#
# ¤ Notes:
#    By default the channel flag 'dronechek' is disabled. Enable it on the channels you wish.
# The only things that you should change are 'drone(*)' (where * stands for a specific setting).

package require Tcl 8.3
package require eggdrop 1.6

namespace eval drone {

  ##
  # .1. Message that will be sent to users upon joining to check either or not it's a drone or a real person:
  set drone(join) {2I am an 4$chan2 eggdrop and I`m verifing if you are an infected person. Please do 4*NOT*2 reply to this message or you`ll get banned !!}

  ##
  # .2. Define the flasg that should be excepted from the on join message:
  set drone(flags) {f|f}

  ##
  # .3. Reason for banning the drones:
  set drone(reason) {Begone drone!}

  ##
  # .4. How much time the ban should last:
  set drone(bantime) {15m}

  ##
  # .5. Define the type of the banmask:
  # 0/1 ~> *!*foo@*.bar.com
  #  2 ~> *!*@moo.bar.com
  #  3 ~> *!*@*.bar.com
  #  4 ~> *!*foo@moo.bar.com
  #  5 ~> *!*foo@*
  set drone(type) {2}

  #
  ## ¤ Don't edit past here unless you know TCL! ¤
  #

  variable version {1.0}
  variable binds {join:check msgm:execute time:t1mer}

  # quick cleanup
  foreach elem [binds] {
    foreach {type flags name hits proc} $elem {
      if {[string match [namespace current]::* $proc]} {
        unbind $type $flags $name $proc
      }
    }
  }

  foreach elem $binds {
    scan $elem {%[^:]:%s} bind name
    bind $bind - * [namespace current]::$name
  }

  # taken from xchannel.tcl by demond@demond.net
  proc maskhost {nuhost {type 0}} {
    scan $nuhost {%[^!]!%[^@]@%s} nick user host
    scan [set mask [::maskhost $nuhost]] {%*[^@]@%s} mhost
    switch $type {
      0 - 1 { return $mask } ;# *!*foo@*.bar.com
      2 { return *!*@$host } ;# *!*@moo.bar.com
      3 { return *!*@$mhost } ;# *!*@*.bar.com
      4 { return *!*$user@$host } ;# *!*foo@moo.bar.com
      5 { return *!*$user@* } ;# *!*foo@*
      6 { return $nuhost }
    }
  }

  proc check {nick uhost hand chan} {
    variable drones; variable drone
    if {![channel get $chan antispam] || [matchattr $hand $drone(flags) $chan]} return
    if {![botisop $chan] || [isbotnick $nick]} return
    set hash [md5 $nick,$uhost]
    if {[info exists drones($hash)]} return
    puthelp "PRIVMSG $nick :[subst $drone(join)]"
    set drones($hash) [unixtime]
  }

  proc execute {nick uhost hand text} {
    variable drones; variable drone
    set hash [md5 $nick,$uhost]
    if {![info exists drones($hash)]} return
    foreach chan [channels] {
      if {![channel get $chan antispam] || ![onchan $nick $chan] || ![botisop $chan]} continue
      newchanban $chan [maskhost $nick!$uhost $drone(type)] Drone? $drone(reason) $drone(bantime)
    }
      purge $hash
  }

  proc t1mer {min hour day month year} {
    variable drones
    foreach {hash data} [array get drones] {
      if {[expr [unixtime] - [set ts [lindex $data 0]]] >= 60} {
        purge $hash
      }
    }
  }

  proc purge {hash} {
    variable drones
    if {![info exists drones($hash)]} return
    unset drones($hash)
  }

  putlog "antispam.tcl v$version loaded.."
}