################
### Emuhaven Protect TCL - by faraway
### email: faraway@mtnweb.com
################
# [0|1] = [OFF|ON]

bind join - * join_proc
bind mode - * mode_proc

bind dcc m chprot cmd_chprt
bind dcc o join cmd_join
bind dcc n chkey cmd_chkey

bind msg o !update msg_update

bind pub o !safe pub_safe
###########################################################################
#set up main channel
set homechan "#emuhaven"

set ctcp-userinfo ""
set ctcp-finger ""

set curver "v0.9"
set curkey 0


set safe_user ""
set chprot 1
set autokey 0
set ctcp-version "\[AtlantiS(v1.2a)\] by Dethnite + faraway's extras + \[emu v.$curver\]" 
putlog "-:::### faraway's emuguard.tcl ###:::-"

proc cmd_chprt {hand idx arg} {
  global chprot
  set jstrn 0
  if {!($chprot)} {
    putdcc $idx "***\[emu\] Channel Protection now ON!"
    set chprot 1
    set jstrn 1
  }
  if {$chprot && $jstrn !=1} {
    putdcc $idx "***\[emu\] Channel Protection now OFF!"
    set chprot 0
}}

proc cmd_chkey {hand idx arg} {
  global autokey
  set jstrn 0
  if {!($autokey)} {
    putdcc $idx "***\[emu\] Auto Notify now ON!"
    set autokey 1
    set jstrn 1
  }
  if {$autokey && $jstrn !=1} {
    putdcc $idx "***\[emu\] Auto Notify now OFF!"
    set autokey 0
}}

proc final_nick_check {nick chan} {
  if {[isop $nick $chan]==1} {
    return 0
  } else {
           putserv "NOTICE $nick :You did not OP yourself within 10 minues!"
           putserv "KICK $chan $nick :You did not OP yourself!"
         }
}
proc check_nick {nick chan} {
  if {[isop $nick $chan]==1} {
    return 0
  } else {
           putserv "NOTICE $nick :You have 5 more minutes remaining."
           timer 5 final_nick_check $nick $chan
         }
}


proc join_proc {nck uhost han channel} {
  global nick chprot date homechan safe_user
  set safe 0
  foreach list $safe_user {
    if {[lsearch -exact [string tolower $list] [string tolower $nck]]==0} {
      set safe 1
      putlog "***\[emu\] $nck - Protected safe user has joined."
    }    
  }
  if {$safe==0} {
    if {$nck!=$nick} {
      if {$chprot} {
        if {!([matchattr $han f]) && (![matchattr $han x]) && (![matchattr $han m]) && (![matchattr $han n]) && (![matchattr $han o])} {
          if {$channel==$homechan} {
            putlog "***\[emu\] Kickbanning $nck from $channel - unknown user!"
            bkout $nck $channel $uhost
          }
        }
      }
    }
  }
  if {[mathattr $han o]==1 && [isop $nck $channel]==0} {
    putserv "NOTICE $nck :You have 10 minutes to op yourself."
    timer 5 check_nick $nck $channel
  }
}

proc bkout {nop channel uhost} {
  global homechan
  if {[lsearch -exact $channel $homechan]==0} {
    putserv "KICK $channel $nop :***\[emu\] I don't remember ever inviting YOU here!" 
    newban [maskhost $uhost] bot "***\[emu\] Fucking keep out of our channel! [date]" 0 
    utimer 5 nxtkey
  }
}

proc mode_proc {nick uhost handle channel modch} {
  if {[regexp "o" [lindex $modch 0]]==1} {
    if {$nick==""} {
      set nop [lindex $modch 1]
      set han [nick2hand $nop $channel]
      putlog "***\[emu\] Warning!! On $channel $nop split in, and was opped by $uhost!" 
      if {!([matchattr $han f]) && (![matchattr $han x]) && (![matchattr $han m]) && (![matchattr $han n]) && (![matchattr $han o])} {
        putlog "***\[emu\] WARNING!!! Lamer not on our group split in with ops, getting rid of him!" 
        putserv "MODE $channel -o $nop"
        bkout $nop $channel [getchanhost $nop $channel]
      }
    }
  }
}

proc putnot {nick msg} {puthelp "NOTICE $nick :$msg" }
proc putmsg {nick msg} {putserv "PRIVMSG $nick :$msg"}
proc putchan {channel msg} {putserv "PRIVMSG $channel :$msg"}
set table {
  {a}
  {b}
  {c}
  {d}
  {e}
  {f}
  {g}
  {h}
  {i}
  {j}
  {k}
  {l}
  {m}
  {n}
  {o}
  {p}
  {q}
  {r}
  {s}
  {t}
  {u}
  {v}
  {w}
  {x}
  {y}
  {z}
}


proc nxtkey {} {
  global homechan
  global curkey
  global table
  set rand_key [lindex $table [rand [llength $table]]]
  set rand_key $rand_key[lindex $table [rand [llength $table]]]
  set rand_key $rand_key[lindex $table [rand [llength $table]]]
  set rand_key $rand_key[lindex $table [rand [llength $table]]]
  set rand_key $rand_key[lindex $table [rand [llength $table]]]
  set newkey $rand_key
  set curkey [expr $curkey+1]
  set ccurkey [lindex [getchanmode $homechan] 1]
  putserv "mode $homechan -k $ccurkey"
  putserv "mode $homechan +k $newkey"
}

# tezt.tcl - use a combination of /ison and /userhost to find users
# of the bots and then send them information.
#
#  by behemoth - valleyrd@earthlink.net (or try efnet #square)
#   notify-info idea by faraway
#
#  whipped this up in 5 minutes, so the code
#  probably has some bugs, but you get the general
#  idea. :-)
#
# .console +2 <- to see debug information

#                ^ nicks to check for

set notify_list ""
set notify_flags "x" ;# flags required for the transfer of stats
set notify_interval "30" ;# interval between notify list checks (secs)
set notify_wrap "225"    ;# num. chars to wrap channel stats at

bind raw - "% 303 % :*" on303
bind raw - "% 302 % :*" on302

proc on303 {out} {
  global notify_active notify_list notify_waiting notify_interval
  if ![info exists notify_active] {set notify_active ""}
  if ![info exists notify_waiting] {set notify_waiting ""}
  set notify_new ""
  set args [string trimleft [lrange $out 3 end] :]
  foreach check $notify_active {
    set i [lsearch -exact [string tolower $args] [string tolower $check]]
    if {$i == -1} {
      putloglev 2 * "<-- active notify user $check expired, stripping from static list"
      set j [lsearch -exact [string tolower $notify_active] [string tolower $check]]
      set notify_active [lreplace $notify_active $j $j]
    }
  }
  foreach info $args {
    set i [lsearch -exact [string tolower $notify_active] [string tolower $info]]
    if {$i == -1} {
      putloglev 2 * "<-- inactive notify user $info introduced, requesting userhost"
      lappend notify_active $info
      lappend notify_new $info
      lappend notify_waiting $info
    }
  }
  if {$notify_new != ""} {
    for {set i 0} {$i<[llength $notify_new]} {incr i 5} {
      putserv "USERHOST :[lrange $notify_new $i [expr $i + 4]]"
      putloglev 2 * "--> USERHOST :[lrange $notify_new $i [expr $i + 4]]"
    }
  }
  foreach timer [utimers] {
    if {[lindex $timer 1] == "refresh_notify"} {
      killutimer [lindex $timer 2]
    }
  }
  utimer $notify_interval refresh_notify
}

proc on302 {out} {
  global notify_waiting notify_flags notify_wrap
  if ![info exists notify_waiting] {set notify_waiting ""}
  set args [string trimleft [lrange $out 3 end] :]
  putloglev 2 * "--- on302() called ---"
  putloglev 2 * $out
  foreach info $args {
    scan $info "%\[^=]=%\[^@\]@%s" nick user host
    set user [string range $user 1 end]
    if {[regexp "~" [string range $user 0 1]]== 1} {
      set user [string range $user 1 end]
    }
    set i [lsearch -exact [string tolower $notify_waiting] [string tolower $nick]]
    if {$i == -1} continue
    set notify_waiting [lreplace $notify_waiting $i $i]
    set nick [string trimright $nick *]
    set u [finduser $nick!$user@$host]
    putloglev 2 * "$nick!$user@$host -> $u \[[chattr $u]\]"
    if [matchattr $u $notify_flags] {
      #putserv "NOTICE $nick :Hi, $u! You activated NOTIFY_SIGNON, so I'm going to send you some channel info. :-)"
      set info ""
      set d ""
      foreach c [channels] {
        set opC 0;set vC 0
        if {[string length $info] > $notify_wrap} {
          putserv "NOTICE $nick :Channels${d}: [string trimright [join $info] ,]"
          set d " (cont.)"
          set info ""
        }
        foreach u [chanlist $c] {
          if [isop $u $c] {incr opC}
          if [isvoice $u $c] {incr vC}
        }
        lappend info "[expr {[botisop $c]?"@":" "}]$c \[[getchanmode $c]\] (U:[llength [chanlist $c]] O:${opC} N:[expr [llength [chanlist $c]] - $opC] V:${vC} B:[llength [chanbans $c]]),"
      }
      if {$info != ""} {
        putserv "NOTICE $nick :Channels${d}: [string trimright [join $info] ,]"
      }
    }
  }
}

proc refresh_notify {} {
  global notify_list autokey
  if {$autokey==1} {
    set notify_list "[userlist x]"
    foreach timer [utimers] {
      if {[lindex $timer 1] == "refresh_notify"} {
        killutimer [lindex $timer 2]
      }
    }
  }
  putserv "ISON :$notify_list"
}

proc pub_safe {nick uhost handle channel args} {
global safe_user
  if {$args!=""} {
    if {[matchattr $handle o]==1} {
      set safe_user "$safe_user [lindex $args 0]"
      putlog "$nick\[$handle\]!$uhost requested that $args be safe!"
      putnot $nick "***\[emu\] User \[[string trimleft $args " "]\] can now enter."
    }
  }
}

proc msg_update {nick uhost handle args} {
  global notify_wrap
  set info ""
  set d ""
  set person_pass [lindex $args 0]
  if {[passwdok $handle $person_pass]==1} {
    putlog "*** \[emu\] $handle\($nick\!$uhost\) !UPDATE!"
    foreach c [channels] {
      set opC 0;set vC 0
      if {[string length $info] > $notify_wrap} {
        putserv "NOTICE $nick :Channels${d}: [string trimright [join $info] ,]"
        set d " (cont.)"
        set info ""
      }
      foreach u [chanlist $c] {
        if [isop $u $c] {incr opC}
          if [isvoice $u $c] {incr vC}
      }
      lappend info "[expr {[botisop $c]?"@":" "}]$c \[[getchanmode $c]\] (U:[llength [chanlist $c]] O:${opC} N:[expr [llength [chanlist $c]] - $opC] V:${vC} B:[llength [chanbans $c]]),"
    }
  } {    
      putlog "*** \[emu\] $handle\($nick\!$uhost\) !UPDATE! failed..."
    }
  if {$info != ""} {
    putserv "NOTICE $nick :Channels${d}: [string trimright [join $info] ,]"
  }
} 
set notify_active ""
timer 1 refresh_notify

# eof
