set x2 10-14ap4n10-10"

# chanset <#channel> <+/->mc.spamcheck
# chanset <#channel> <+/->mc.spamcycle
set nb_component(mcspam) 1

set mc_sc(:config:ign:wrds) "addhost info who ident help voice whois pass op invite go key die jump memory save rehash reset status dent notes auth"
set mc_sc(:config:act:wrds) {
 *geocities*
 */*
 *h|*
 *kontol*
 *fuck*
 *.com*
 *.org*
 *.net*
 *.info*
 *.tk*
 *.ws*
 *.biz*
 *.edu*
 *join*
 *come*
 *site*
 *ch.*
 *http*
 *babes*
 *http://*
 *www.*
 *sex*
 *join #*
 *goto #*
 *ftp.*
 *http://www.*
 *Click Link*
 *joi*
 *klik*
 *j #*
 *goto #*
 *irc.*
 *#*
 *server*
 *doubleclick*
 *FREE PORN:*
 *Halo nalan yuk*
 *Free Pics For*
 *di #*
 *Dapatkan biodata*
 *FANTASY GIRLS*
 *Free XXX Pussy*
 *pussy*
 *free*
 *click*
 *website*
 *cli*
}

set mc_sc(:config:act:strip) 1
set mc_sc(:config:sc:cyclerate) 3:12
set mc_sc(:config:ircnicks) ""
set mc_sc(:config:cycle_opped_flags) +b|-
set mc_sc(:config:nocycle:mode) "+i +R +r +m +M"
set mc_sc(:config:joind) 0
set mc_sc(:config:chan:cycle:message) ""
set mc_sc(:config:exempt:op) 1
set mc_sc(:config:exempt:voice) 0
set mc_sc(:config:exempt:flags) "bn|n"
set mc_sc(:config:warnings) 0
set mc_sc(:config:warn:message:dccsend) "${x2} don't try to send me %filename!"
set mc_sc(:config:warn:message:privmsg) "${x2} \002K\002ick\002B\002an\002!\002 Mass \002Inv/Adv\002 Is Prohibited!"
set mc_sc(:config:warn:message:notice) "${x2} \002K\002ick\002B\002an\002!\002 Mass \002Inv/Adv\002 Is Prohibited!"
set mc_sc(:config:warn:message:invite) "${x2} \002K\002ick\002B\002an\002!\002 Mass \002Inv/Adv\002 Is Prohibited!"
set mc_sc(:config:warn:kick) 0
set mc_sc(:config:warn:ban) 0
set mc_sc(:config:exc:ban) 0
set mc_sc(:config:exc:message:privmsg) "${x2} \002K\002ick\002B\002an\002!\002 Mass \002Inv/Adv\002 Is Prohibited!"
set mc_sc(:config:exc:message:notice) "${x2} \002K\002ick\002B\002an\002!\002 Mass \002Inv/Adv\002 Is Prohibited!"
set mc_sc(:config:exc:message:invite) "${x2} \002K\002ick\002B\002an\002!\002 Mass \002Inv/Adv\002 Is Prohibited!"
set mc_sc(:config:bant) 2
set mc_sc(:config:relay) 1
set mc_sc(:config:relay:key) "has~ANTI-APSM986sdf0hKEY~JZSN~EX0"
#set mc_sc(:config:relay:noopbots) "PRIVMSG ${x2} ANTISPAM - Found nick: %nick method: %method msg: %message"
set mc_sc(:config:relay:noopbots) ""
set mc_sc(:config:ban:anyhow) 1
set mc_sc(:config:enable:msgcmd) 0
set mc_sc(:config:svs:enable) 1

#Script:mc_sc
catch {unset temp}
set mc_sc(info:vars) ""
foreach {temp(name) temp(value)} [array get mc_sc :config:*] {
  lappend mc_sc(info:vars) [list $temp(name) $temp(value)]
}
set mc_sc(info:loc) [info script]
array set mc_sc [list \
  script                 "Spam Check" \
  version                "v2.5.2" \
  svs:script             "spamcheck" \
  svs:version            "002005002000" \
  svs:client_version     "v4.0.2" \
  svs:client_svs_version "004000002000" \
  svs:server             "mc.svs.purehype.net" \
  svs:port               "81" \
  svs:get                "/index.tcl"]
set mc_sc(svs:query)    "svs=$mc_sc(svs:script)&"
append mc_sc(svs:query) "version=$mc_sc(svs:version)&"
append mc_sc(svs:query) "svs_version=$mc_sc(svs:client_svs_version)"

if {![info exists numversion] || 
    ([string range $numversion 0 4] < "10613") ||
    (([string range $numversion 0 4] == "10613") &&
     ([string range $numversion 5 6] != "00"))} {
  set temp(tag) "$mc_sc(script) $mc_sc(version)"
  putloglev o * \
    "$temp(tag) by MC_8 will only work on eggdrop 1.6.13 or greater."
  putloglev o * "$temp(tag)  will not work with eggdrop $version."
  putloglev o * "$temp(tag)  not loaded."
  return 1
}

setudef flag mc.spamcycle; setudef flag mc.spamcheck

# Error system, v3.1
proc mc:sc:error {command error arg} {
  global mc_sc version lastbind errorInfo
  putlog "Error in script $mc_sc(script) $mc_sc(version)."
  putlog "    Error System: v3.0"
  putlog "       Last Bind: [expr {[info exists lastbind]?$lastbind:"-NULL-"}]"
  putlog "         Command: $command"
  putlog "       Arguments: $arg"
  putlog "       Error Msg: $error"
  putlog "    Egg. Version: [expr {[info exists version]?$version:"-NULL-"}]"
  putlog "     TCL Version: [info tclversion]"
  putlog "  TCL Patchlevel: [info patchlevel]"
  putlog "*** Please submit this bug so MC_8 can fix it.  Visit"
  putlog "*** http://mc.purehype.net:81/bugzilla/ to properly report the bug."
  putlog \
    "*** Please include ALL info. in the bug report, including the next(s)."
  error $errorInfo
}

proc mc:sc:errchk {command arg} {
  lappend ::lastCommand "$command $arg"
  set ::lastCommand\
    [lrange $::lastCommand [expr [llength $::lastCommand]-5] end]
  if {![catch {eval $command $arg} return]} {return $return}
  mc:sc:error $command $return $arg
  return 0
}
# ^

if {![string match *mc:sc:cycle* [timers]]} {
  scan $mc_sc(:config:sc:cyclerate) {%[^:]:%s} min max
  if {$min >= $max} {set cycletime $max} {
    while {[set cycletime [rand [expr $max+1]]] < $min} {}
  }; timer $cycletime mc:sc:cycle
}
catch {unset mc_sc(joind:active)}

bind dcc m| spamcheck mc:sc:dcc:command:spamcheck
proc mc:sc:dcc:command:spamcheck {hand idx arg} {
  return [mc:sc:errchk mc:sc:dcc:command:spamcheck_ [list $hand $idx $arg]]
}
proc mc:sc:dcc:command:spamcheck_ {hand idx arg} {
  global mc_sc
  set chan [lindex [split $arg] 0]
  if {[validchan $chan]} {
    if {![mc:sc:chanflag $chan mc.spamcheck] ||
        ![mc:sc:chanflag $chan mc.spamcycle]} {
      set temp(x) "mc.spamcheck and mc.spamcycle"
      putdcc $idx \
       "$mc_sc(script):  $chan doesn't have the $temp(x) channel flags enabled."
      return 0
    }
    putdcc $idx "$mc_sc(script): Cycling $chan..."
    mc:sc:cycle $chan
  } else {
    putdcc $idx "$mc_sc(script): Cycling [join [channels] ", "]..."
    mc:sc:cycle
  }; return 1
}

bind msg m| spamcheck mc:sc:msg:command:spamcheck
proc mc:sc:msg:command:spamcheck {nick uhost hand arg} {
  return [mc:sc:errchk mc:sc:msg:command:spamcheck_ \
    [list $nick $uhost $hand $arg]]
}
proc mc:sc:msg:command:spamcheck_ {nick uhost hand arg} {
  global mc_sc
  if {!$mc_sc(:config:enable:msgcmd)} {return 0}
  set chan [lindex [split $arg] 0]
  if {[validchan $chan]} {
    if {![mc:sc:chanflag $chan mc.spamcheck] ||
        ![mc:sc:chanflag $chan mc.spamcycle]} {
      set temp(x) "mc.spamcheck and mc.spamcycle channel flags"
      set temp() "$chan doesn't have the $temp(x) enabled"
      puthelp "PRIVMSG $nick :$mc_sc(script):  $temp()."
      return 0
    }
    puthelp "PRIVMSG $nick :$mc_sc(script): Cycling $chan..."
    mc:sc:cycle $chan
  } else {
    puthelp "PRIVMSG $nick :$mc_sc(script): Cycling [join [channels] ", "]..."
    mc:sc:cycle
  }; return 1
}

proc mc:sc:cycle {{chan ""}} {
  return [mc:sc:errchk mc:sc:cycle_ [list $chan]]
}
proc mc:sc:cycle_ {chan} {
  global mc_sc numversion botnick
  set return 0
  if {[validchan $chan]} {set channels $chan} \
  else {set channels [channels]}
  foreach chan [string tolower $channels] {
    if {![mc:sc:chanflag $chan mc.spamcheck] ||
        ![mc:sc:chanflag $chan mc.spamcycle]} {continue}
    set cache(chanlist) [chanlist $chan]
    if {[botisop $chan]} {
      set onlyop 1
      foreach user $cache(chanlist) {
        if {![isbotnick $user] && [isop $user $chan]} {set onlyop 0; break}
      }
      if {$onlyop} {
        putlog "$mc_sc(script):  Cannot cycle $chan, I am the only op."
        continue
      }
    }
    set i 0
    foreach user $cache(chanlist) {
      if {[isop $user $chan] && (($mc_sc(:config:cycle_opped_flags) == "-|-") ||
          ([matchattr [nick2hand $user $chan] $mc_sc(:config:cycle_opped_flags) $chan]))} {
        set i 1
        break
      }
    }
    if {!$i} {
      putlog "$mc_sc(script):  Cannot cycle $chan, no acceptable ops."
      continue
    }
    set channel_mode [lindex [split [getchanmode $chan]] 0]
    set pos_chan_mode "" ; set neg_chan_mode ""
    regexp -- {\+([a-zA-Z0-9]*)[^a-zA-Z0-9]?} $channel_mode temp(x) \
      pos_chan_mode
    regexp -- {\-([a-zA-Z0-9]*)[^a-zA-Z0-9]?} $channel_mode temp(x) \
      neg_chan_mode
    set continue 0
    foreach nocymode $mc_sc(:config:nocycle:mode) {
      set pos_mode "" ; set neg_mode ""
      regexp -- {\+([a-zA-Z0-9]*)[^a-zA-Z0-9]?} $nocymode temp(x) pos_mode
      regexp -- {\-([a-zA-Z0-9]*)[^a-zA-Z0-9]?} $nocymode temp(x) neg_mode
      set a 1
      foreach mode [split $pos_mode ""] {
        if {![string match *$mode* $pos_chan_mode]} {set a 0; break}
      }
      set b 1
      foreach mode [split $neg_mode ""] {
        if {![string match *$mode* $neg_chan_mode]} {set b 0; break}
      }
      set c 1
      foreach mode [split $neg_mode ""] {
        if {[string match *$mode* $pos_chan_mode]} {set c 0; break}
      }
      if {$a && $b && $c} {set continue 1; break}
    }
    if {$continue} {
      set temp(x) "'$channel_mode' and nocycle mode is '$nocymode'"
      putlog "$mc_sc(script): Cannot cycle $chan, channel mode is $temp(x)."
      continue
    }
    if {($numversion >= "1032800") && $mc_sc(:config:joind)} {
      if {![mc:sc:chanflag $chan inactive]} {
        channel set $chan +inactive
        utimer $mc_sc(:config:joind) [list channel set $chan -inactive]
        set temp(cmd) [list catch "unset mc_sc(joind:active)"]
       if {[lsearch -glob [utimers] *[mc:sc:filter -tcl $temp(cmd)]*] == "-1"} {
          utimer [expr $mc_sc(:config:joind)+[expr [llength [channels]]*5]] \
            $temp(cmd)
        }; set mc_sc(joind:active) 1
      }
    } else {
      if {$mc_sc(:config:chan:cycle:message) != ""} {
        putserv "PART $chan :$mc_sc(:config:chan:cycle:message)"
      } else {putserv "PART $chan"}
    }
  }
  scan $mc_sc(:config:sc:cyclerate) {%[^:]:%s} min max
  if {$min >= $max} {set cycletime $max} {
    while {[set cycletime [rand [expr $max+1]]] < $min} {}
  }; if {![string match *mc:sc:cycle* [timers]]} {timer $cycletime mc:sc:cycle}
}

bind raw - PART mc:sc:raw:part
proc mc:sc:raw:part {from key text} {
  return [mc:sc:errchk mc:sc:raw:part_ [list $from $key $text]]
}
proc mc:sc:raw:part_ {from key text} {
  global mc_sc nick altnick
  set nik [lindex [split $from !] 0]
  set uhost [join [lrange [split $from !] 1 end] !]
  set hand [finduser $from]
  set cache(stext) [split $text]
  set chan [lindex $cache(stext) 0]
  # This will compensate for undernet's ircu upgrade witch changes where : is to
  # be.  Should be, at the last argument -- old undernet ircu just put it on the
  # part message only (if no part message, should go in front of the channel
  # name.
  if {[llength $cache(stext)] == "1"} {regsub -- {^:?(.*)$} $chan \\1 chan}
  if {![isbotnick $nik] || ![validchan $chan] ||
      ($mc_sc(:config:ircnicks) == "") ||
      ![mc:sc:chanflag $chan mc.spamcheck] ||
      ![mc:sc:chanflag $chan mc.spamcycle]} {return 0}
  set array_name [list :: ignore part]
  if {[info exists mc_sc($array_name)]} {return 0}
  set mc_sc($array_name) [clock seconds]
  utimer [llength [channels]] [list unset mc_sc($array_name)]
  set temp(split_nicks) [split $mc_sc(:config:ircnicks)]
  set array_name [list :: last nick]
  if {![info exists mc_sc($array_name)]} {set mc_sc($array_name) -1}
  incr mc_sc($array_name)
  if {$mc_sc($array_name) >= [llength $temp(split_nicks)]} {
    set mc_sc($array_name) 0
  }
  set altnick $nick
  set nick [lindex $temp(split_nicks) $mc_sc($array_name)]
  return 0
}

bind raw - INVITE mc:sc:raw:invite
proc mc:sc:raw:invite {from key arg} {
  return [mc:sc:errchk mc:sc:raw:invite_ [list $from $key $arg]]
}
proc mc:sc:raw:invite_ {from key arg} {
  global mc_sc botnick
  if {$mc_sc(:config:warn:message:invite) == ""} {return 0}
  scan $from {%[^!]!%s} nick uhost
  set hand [finduser $from]
  set chan [lindex [split $arg] 1]
  regexp -- {^:(.*)$} $chan dummy chan
  if {$mc_sc(:config:act:strip)} {set chan [mc:sc:mirc_strip -all -- $chan]}
  set arg "invite $chan"
  set return 0
  foreach word [string tolower [split $mc_sc(:config:act:wrds) \n]] {
    set word [string trimleft $word " "]
    if {$word == ""} {continue}
    if {[string match $word [string tolower $arg]]} {
      set return 0; break
    }
  }
  if {$return} {return 0}
  mc:sc:message $nick $uhost $hand invite "" "!INVITE to $chan!"
  return 0
}

bind notc - * mc:sc:notc:message
proc mc:sc:notc:message {nick uhost hand arg {dest ""} {DCC_Check ""}} {
  set temp() [list $nick $uhost $hand $arg $dest $DCC_Check]
  return [mc:sc:errchk mc:sc:notc:message_ $temp()]
}
proc mc:sc:notc:message_ {nick uhost hand arg {dest ""} {DCC_Check ""}} {
  global mc_sc botnick
  if {$dest == ""} {set dest $botnick}
  if {![isbotnick $dest] || ($mc_sc(:config:warn:message:notice) == "")} {
    return 0
  }
  if {[string match "DCC *" $arg] && ($DCC_Check == "")} {
    utimer 5 [list mc:sc:notc:message $nick $uhost $hand $arg $dest DCC_Check]
    return 0
  }
  if {$mc_sc(:config:act:strip)} {set arg [mc:sc:mirc_strip -all -- $arg]}
  set return 1
  foreach word [string tolower [split $mc_sc(:config:act:wrds) \n]] {
    set word [string trimleft $word " "]
    if {$word == ""} {continue}
    if {[string match $word [string tolower $arg]]} {
      set return 0; break
    }
  }; if {$return} {return 0}
  scan $arg %s cmd
  set temp() [split [string tolower $mc_sc(:config:ign:wrds)]]
  if {[lsearch -exact $temp() [string tolower $cmd]] >= "0"} {
    return 0
  }; mc:sc:message $nick $uhost $hand notice "" "!NOTICE! $arg"
}

bind msgm - * mc:sc:msgm:message
proc mc:sc:msgm:message {nick uhost hand arg} {
  return [mc:sc:errchk mc:sc:msgm:message_ [list $nick $uhost $hand $arg]]
}
proc mc:sc:msgm:message_ {nick uhost hand arg} {
  global mc_sc
  if {$mc_sc(:config:warn:message:privmsg) == ""} {return 0}
  if {$mc_sc(:config:act:strip)} {set arg [mc:sc:mirc_strip -all -- $arg]}
  set return 1
  foreach word [string tolower [split $mc_sc(:config:act:wrds) \n]] {
    set word [string trimleft $word " "]
    if {$word == ""} {continue}
    if {[string match $word [string tolower $arg]]} {
      set return 0; break
    }
  }; if {$return} {return 0}
  scan $arg %s cmd
  set temp() [split [string tolower $mc_sc(:config:ign:wrds)]]
  if {[lsearch -exact $temp() [string tolower $cmd]] >= "0"} {
    return 0
  }; mc:sc:message $nick $uhost $hand privmsg "" "!PRIVMSG! $arg"
}

bind ctcp - "DCC" mc:sc:dcc:message
proc mc:sc:dcc:message {nick uhost hand dest keyword arg} {
  set temp() [list $nick $uhost $hand $dest $keyword $arg]
  return [mc:sc:errchk mc:sc:dcc:message_ $temp()]
}
proc mc:sc:dcc:message_ {nick uhost hand dest keyword arg} {
  global mc_sc botnick
  scan $arg {%s %s %s %s %s} cmd file ip port size
  if {($mc_sc(:config:warn:message:dccsend) == "") ||
      ($cmd != "SEND") ||
      ![isbotnick $dest]} {return 0}
  set arg "dccsend $file"
  foreach utimer [string tolower [utimers]] {
    set timer [lindex $utimer 1]
    set t_arg [lindex $timer 4]
    set t_dest [lindex $timer 5]
    set t_dcc_test [lindex $timer 6]
    set t_cmd [list mc:sc:notc:message $nick $uhost $hand $t_arg $t_dest \
      $t_dcc_test]
    if {$timer == [string tolower $t_cmd]} {
      killutimer [lindex $utimer 2]; break
    }
  }; if {$mc_sc(:config:act:strip)} {set arg [mc:sc:mirc_strip -all -- $arg]}
  set return 1
  foreach word [string tolower [split $mc_sc(:config:act:wrds) \n]] {
    set word [string trimleft $word " "]
    if {$word == ""} {continue}
    if {[string match $word [string tolower $arg]]} {
      set return 0; break
    }
  }
  if {$return} {return 0}
  mc:sc:message $nick $uhost $hand $arg "" "!DCCSEND $file!"
}

proc mc:sc:message {nick uhost hand method channels message} {
  return [mc:sc:errchk mc:sc:message_ \
    [list $nick $uhost $hand $method $channels $message]]
}
proc mc:sc:message_ {nick uhost hand method channels message} {
  global mc_sc botnick
  if {[isbotnick $nick]} {return 0}
  set temp(split_uhost) [split $uhost @]
  set ident [join [lrange $temp(split_uhost) 0 \
    [expr [llength $temp(split_uhost)]-2]] @]
  set host [lindex $temp(split_uhost) end]
  set cache(channels) [channels]
  set cache(lchannels) [string tolower $cache(channels)]
  if {$channels == ""} {
    set cache(cmd) [list catch "unset mc_sc(ignore:$nick)"]
    if {[info exists mc_sc(ignore:$nick)]} {
      if {[lsearch -glob [utimers] *[mc:sc:filter -tcl $cache(cmd)]*] == "-1"} {
        utimer 5 $cache(cmd)
      }; return 0
    }; set mc_sc(ignore:$nick) 1
    utimer 5 $cache(cmd)
    if {[info exists mc_sc(joind:active)]} {
      utimer [expr $mc_sc(:config:joind)+2] \
        [list mc:sc:message $nick $uhost $hand $method $channels $message]
      set cache(cmd) [list catch "unset mc_sc(joind:active)"]
      if {[lsearch -glob [utimers] *[mc:sc:filter -tcl $cache(cmd)]*] == "-1"} {
        utimer $mc_sc(:config:joind) $cache(cmd)
      }; return 0
    }
    foreach chan $cache(lchannels) {
      if {[onchan $nick $chan]} {lappend channels $chan}
    }
    if {$channels == ""} {
      set found ""
      foreach chan $cache(lchannels) {
        append found " [mc:sc:findnicks *!*@$host $chan]"
      }
      if {$found == ""} {set channels $cache(lchannels)} \
      else {
        foreach user $found {
          utimer 5 [list mc:sc:message $user [getchanhost $user] \
            [nick2hand $user] $method $channels $message]
        }; return 0
      }
    }
  } elseif {![onchan $nick $channels]} {return 0}
  foreach channel $channels {
    if {([mc:sc:chanflag $channel inactive]) ||
        (![mc:sc:chanflag $channel mc.spamcheck]) ||
        (([isop $nick $channel]) && ($mc_sc(:config:exempt:op))) ||
        (([isvoice $nick $channel]) && ($mc_sc(:config:exempt:voice))) ||
        (($mc_sc(:config:exempt:flags) != "") &&
        ([matchattr $hand $mc_sc(:config:exempt:flags) $channel]))} {continue}
    if {![botonchan $channel]} {
      utimer [expr $mc_sc(:config:joind)+2] [list mc:sc:message $nick $uhost \
        $hand $method $channel $message]
      continue
    }
    if {$mc_sc(:config:warnings)} {
      set array_name [list :: warn $host $channel]
      if {![info exists mc_sc($array_name)]} {set mc_sc($array_name) -1}
      incr mc_sc($array_name)
      if {$mc_sc($array_name) > $mc_sc(:config:warnings)} {set give_warn 0} \
      else {set give_warn 1}
    } else {set give_warn 0}
    mc:sc:punish $nick $uhost $hand $channel $give_warn $method $message
  }
}

proc mc:sc:punish {nick uhost hand chan warn method message} {
  return [mc:sc:errchk mc:sc:punish_ \
    [list $nick $uhost $hand $chan $warn $method $message]]
}
proc mc:sc:punish_ {nick uhost hand chan warn method message} {
  global mc_sc botnick {botnet-nick}
  if {![mc:sc:chanflag $chan mc.spamcheck]} {return 0}
  set cache(botisop) [botisop $chan]
  set x_done ""
  
  set filename [join [lrange [split $method] 1 end]]
  set method [lindex [split $method] 0]
  set banmask [mc:sc:maskhostbytype $nick!$uhost $mc_sc(:config:bant)]

  if {!$cache(botisop) && $mc_sc(:config:relay)} {
    set temp(list) [list $mc_sc(:config:relay:key) $nick $uhost $hand $chan \
      $warn "$method $filename"]
    if {[validchan $chan]} {
      set found 0
      foreach user [userlist +b|] {
        if {[isop [hand2nick $user] $chan] && [islinked $user]} {
          putbot $user "spamcheck [encrypt \
            "$mc_sc(:config:relay:key)+${botnet-nick}" $temp(list)]"
          set found 1
        }
      }
      if {$found} {lappend x_done "relayed (not opped)"} \
      elseif {($mc_sc(:config:relay:noopbots) != "") && ($message != "")} {
        # $message will only be equal to "" when punishing from a relay.
        set split [split $mc_sc(:config:relay:noopbots)]
        set to [lindex $split 0]
        set msg [join [lrange $split 1 end]]
        set temp(x) [list %filename $filename]
        set msg [mc:sc:replace -- $msg \
          [list %nick $nick %method $method %message $message]]
        foreach user [chanlist $chan] {
          if {![isop $user $chan]} {continue}
          putserv "$to $chan :$msg"
        }
        lappend x_done "$to'd ops (not opped)"
      }
    } else {
      set found 0
      set chan_list [list]
      set bot_list [list]
      foreach channel [channels] {
        
        foreach user [chanlist $channel] {
          if {$user == $nick} {
          
            set found2 0
            foreach user [userlist +b|] {
              if {[isop [hand2nick $user] $channel] && [islinked $user]} {
                lappend bot_list $user
                set found2 1
              }
            }
            if {!$found2} {
              lappend chan_list $channel
              if {![botisop $channel]} {set found 1}
            }
            
          }
        }
        
      }
      
      if {$found} {
        foreach user $bot_list {
          putbot $user "spamcheck [encrypt \
              "$mc_sc(:config:relay:key)+${botnet-nick}" $temp(list)]"
        }
        lappend x_done "relayed (not opped)"
      } elseif {($mc_sc(:config:relay:noopbots) != "") && ($message != "")} {
        # $message will only be equal to "" when punishing from a relay.
        set split [split $mc_sc(:config:relay:noopbots)]
        set to [lindex $split 0]
        set msg [join [lrange $split 1 end]]
        set temp(x) [list %filename $filename]
        set msg [mc:sc:replace -- $msg \
          [list %nick $nick %method $method %message $message]]
        foreach user [chanlist $channel] {
          if {![isop $user $channel]} {continue}
          putserv "$to $channel :$msg"
        }
        lappend x_done "$to'd ops (not opped)"
      }
       
    }
  }
  
  if {!$cache(botisop) && $mc_sc(:config:ban:anyhow) &&
      ![isban $banmask $chan] &&
      ([string trim $mc_sc(:config:exc:ban) @!] > "0")} {
    set temp(x) [list %filename $filename]
    set comment [mc:sc:replace -- $mc_sc(:config:exc:message:$method) $temp(x)]
    if {[string match *! $mc_sc(:config:exc:ban)]} {set options sticky} \
    else {set options none}
    set time [string trim $mc_sc(:config:exc:ban)@!]
    newban $banmask ${botnet-nick} $comment $time $options
    lappend x_done "banned (global) (ban list - [duration $time])"
  } else {
    if {$warn} {
      set temp(x) [list %filename $filename]
      set comment [mc:sc:replace -- \
        $mc_sc(:config:warn:message:$method) $temp(x)]
      if {$mc_sc(:config:warn:msg) && ($comment != "")} {
        puthelp "PRIVMSG $nick :$comment"
        lappend x_done "warn messaged"
      }
      set global [string match @* $mc_sc(:config:warn:ban)]
      if {[string match *! $mc_sc(:config:warn:ban)]} {set opt sticky} \
      else {set opt none}
      set time [string trimleft $mc_sc(:config:warn:ban) @!]
      if {$mc_sc(:config:warn:kick)} {
        if {$comment != ""} {set x " :$comment"} else {set x ""}
        putserv "KICK $chan $nick$x"
        lappend x_done "warn kicked"
      }
    } else {
      set temp(x) [list %filename $filename]
      set comment [mc:sc:replace -- \
        $mc_sc(:config:exc:message:$method) $temp(x)]
      set global [string match @* $mc_sc(:config:exc:ban)]
      if {[string match *! $mc_sc(:config:exc:ban)]} {set opt "sticky"} \
      else {set opt "none"}
      set time [string trimleft $mc_sc(:config:exc:ban) @!]
      if {$comment != ""} {set x " :$comment"} else {set x ""}
      putserv "KICK $chan $nick$x"
      lappend x_done "kicked"
    }
    if {$global} {set channels [string tolower [channels]]} \
    else {set channels [list [string tolower $chan]]}
    foreach channel $channels {
      if {![mc:sc:chanflag $channel mc.spamcheck]} {continue}
      if {($time >= "0") && ![ischanban $banmask $channel]} {
        pushmode $channel +b $banmask
        lappend x_done "banned ($channel) (server)"
      }
      if {($time >= "1") && ![isban $banmask $channel]} {
        newchanban $channel $banmask ${botnet-nick} $comment $time $opt
        lappend x_done "banned ($chan) (ban list - [duration $time])"
      }
    }
  }
  set temp() "Detected $nick ($uhost) spamming $chan"
  putlog "$mc_sc(script): $temp() ([join $x_done ", "])."
  return 1
}

bind bot - spamcheck mc:sc:bot:relay
proc mc:sc:bot:relay {from command arg} {
  return [mc:sc:errchk mc:sc:bot:relay_ [list $from $command $arg]]
}
proc mc:sc:bot:relay_ {from command arg} {
  global mc_sc botnick
  set arg [decrypt "$mc_sc(:config:relay:key)+$from" $arg]
  set key [lindex $arg 0]
  if {$key != $mc_sc(:config:relay:key)} {return 0}
  set nick [lindex $arg 1]; set uhost [lindex $arg 2]; set hand [lindex $arg 3]
  set chan [lindex $arg 4]; set warn [lindex $arg 5]; set method [lindex $arg 6]
  if {!$mc_sc(:config:relay) || ![validchan $chan] ||
      ![mc:sc:chanflag $chan mc.spamcheck]} {return 0}
  set array_name [list :: relayblock [string tolower $nick] \
    [string tolower $chan]]
  set cache(cmd) [list unset mc_sc($array_name)]
  if {[info exists mc_sc($array_name)]} {
    if {[lsearch -glob [utimers] *[mc:sc:filter -tcl $cache(cmd)]*] == "-1"} {
      utimer 10 $cache(cmd)
    }; return 0
  }
  set mc_sc($array_name) [clock seconds]
  utimer 10 $cache(cmd)
  putlog \
    "$mc_sc(script):  Spam detection relay from $from regarding $nick @ $chan."
  mc:sc:punish $nick $uhost $hand $chan $warn $method ""
}

bind evnt - prerestart mc:sc:evnt:prestart
proc mc:sc:evnt:prestart {type} {
  return [mc:sc:errchk mc:sc:evnt:prestart_ [list $type]]
}
proc mc:sc:evnt:prestart_ {type} {
  set i 0
  foreach timer [utimers] {
    if {[string match "*channel set * -inactive*" $timer]} {
      catch [lindex $timer 1]
      killutimer [lindex $timer 2]
      set i 1
    }
  }; if {$i} {savechannels}
}

## More Tools quick procs.
## -- http://mc.purehype.net/script_info.tcl?script=moretools

# badargs <args> <min_llength> <max_llength|end> <argNames>
#     version:
#       v1.0
proc mc:sc:badargs {{args ""}} {
  if {[llength $args] < 4} {
    error {
   wrong # args: should be "mc:sc:badargs args min_llength max_llength argNames"
    }
  }

  set index 0
  foreach varName [list args min max names] {
    set check_$varName [lindex $args $index]
    incr index
  }

  if {[regexp -- {([^0-9])} $check_min -> bad]} {
    error "bad number \"$bad\" in: $check_min"
  }
  if {[regexp -- {([^0-9])} $check_max -> bad] && ($check_max != "end")} {
    error "bad number \"$bad\" in: $check_max"
  }

  # Make sure $check_args is in list format, if not then make it so.
  # Were not going to use 2list here, don't want to evoke a 'too many nested
  # calls to Tcl_EvalObj' error since '2list' uses on this proc.
  if {[catch {llength $check_args} llength]} {
    set check_args [split $check_args]
    set llength $check_args
  }

  if {($llength < $check_min) ||
      (($llength != "end") && ($llength > $check_max))} {
    if {[info level] == "1"} {return 1}
    error "wrong # args: should be \"[lindex [info level -1] 0] $check_names\""
  }; return 0
}

# unlist <argsList> [varName1] [varName2] ... [varNameN]
#     version:
#       v1.0
proc mc:sc:unlist {{args ""}} {
  mc:sc:badargs $args 1 end "argsList ?varName varName ...?"
  set argList [lindex $args 0]
  set argList [expr {([catch {llength $argList}])?[split $argList]:$argList}]
  set argNames [lrange $args 1 end]
  if {![llength $argNames]} {
    return [expr {(![catch {llength $argList}])?
      [join $argList]:$argList}]
  }
  for {set index 0} {$index < [llength $argNames]} {incr index 1} {
    set argName     [lindex $argNames $index]
    set argListItem [lindex $argList  $index]

    set argName_ [expr {([catch {llength $argName}])?[split $argName]:$argName}]
    set setTo   [lindex $argName_ 1]
    set argName [lindex $argName_ 0]

    if {$argName == ""} {continue}

    upvar 1 $argName var

    if {[expr $index+1] > [llength $argList]} {
      if {[llength $argName_] == "2"} {set var $setTo}
    } else {
      if {$argName == "args"} {
        set var [lrange $argList $index end]
        incr index [expr [llength $var]-1]
      } else {set var $argListItem}
    }
  }; return $index
}

# 2list <text>
#     version:
#       v1.0
proc mc:sc:2list {{args ""}} {
  mc:sc:badargs $args 1 1 "text"
  mc:sc:unlist $args text

  return [expr {([catch {llength $text}])?[split $text]:$text}]
}

# maskhostbytype <nick!ident@host.domain> [type]
#     version:
#       v2.1
proc mc:sc:maskhostbytype {{args ""}} {
  mc:sc:badargs $args 1 2 "nick!ident@host.domain ?type?"
  mc:sc:unlist $args nuhost type

  set type [expr {($type == "")?5:$type}]
  if {![regexp -- {^1?[0-9]$} $type]} {
    set valid "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 {or 19}"
    error "bad type \"$type\": must be [join $valid ", "]"
  }

  # Define the maximum length the ircd allows for an ident.  Standard is 9,
  # however I made it to a variable incase someone wants to change it up.
  set ident_max-length 9

  # Define the maximum length the ircd allows for a hostname/ ip.  Standard is
  # 63, however I made it to a variable incase someone wants to change it up.
  set host_max-length 63

  if {![regexp -- {^(.*[^!])!((.*)@(.*))$} $nuhost -> nick uhost ident host]} {
    error "invalid nick!ident@host.domain: $nuhost"
  }

  set maskhost 1
  if {[string length $type] == "2"} {
    # Type must be 10-19.
    if {[info tclversion] < "8.1"} {
      set re_syntax_1 {([12][0-9][0-9]|[1-9][0-9]|[1-9])}
      set re_syntax_2 {([12][0-9][0-9]|[1-9][0-9]|[0-9])}
    } else {
      set re_syntax_1 {([12]\d{2}|[1-9][0-9]|[1-9])}
      set re_syntax_2 {([12]\d{2}|[1-9][0-9]|[0-9])}
    }
    set re_syntax ^$re_syntax_1\\.$re_syntax_2\\.$re_syntax_2\\.$re_syntax_2\$

    if {![regexp -- $re_syntax $host]} {
      regsub -all -- {[0-9]} $host ? host
      set maskhost 0
    }; set type [string index $type 1]
  }

  # Previous version used regexp instead of these string matches.  String match
  # in this case is ~3 microseconds faster.
  if {[string match {[0-4]} $type]} {set nick *}
  if {[string match {[2479]} $type]} {set ident *}
  if {[string match {[1368]} $type]} {regsub -- {^~?(.*)$} $ident *\\1 ident}
  if {[string match {[3489]} $type] && $maskhost} {
    set host [lindex [split [maskhost $host] @] end]
  }

  if {[set length [string length $ident]] > ${ident_max-length}} {
    set ident *[string range $ident [expr $length-${ident_max-length}] end]
  }
  if {[set length [string length $host]] > ${host_max-length}} {
    set host *[string range $host [expr $length-${host_max-length}] end]
  }

  return $nick!$ident@$host
}

# replace [switches] <text> <substitutions>
#     version:
#       v1.3
proc mc:sc:replace {{args ""}} {
  mc:sc:badargs $args 2 4 "?switches? text substitutions"
  set switches ""
  for {set i 0} {[string match -* [set arg [lindex $args $i]]]} {incr i} {
    if {![regexp -- {^-(nocase|-)$} $arg -> switch]} {
      error "bad switch \"$arg\": must be -nocase, or --"
    }
    if {$switch == "-"} {
      incr i
      break
    }; lappend switches $switch
  }
  set nocase [expr {([lsearch -exact $switches "nocase"] >= "0") ? 1 : 0}]
  set text [lindex $args $i]
  set substitutions [lindex $args [expr $i+1]]
  mc:sc:badargs [lrange $args $i end] 2 2 "?switches? text substitutions"

  # Check to see if $substitutions is in list format, if not make it so.
  set substitutions [mc:sc:2list $substitutions]

  if {[info tclversion] >= "8.1"} {
    return [expr {($nocase)?
      [string map -nocase $substitutions $text]:
      [string map $substitutions $text]}]
  }

  set re_syntax {([][\\\*\+\?\{\}\,\(\)\:\.\^\$\=\!\|])}
  foreach {a b} $substitutions {
    regsub -all -- $re_syntax $a {\\\1} a
    if {$nocase} {regsub -all -nocase -- $a $text $b text} \
    else {regsub -all -- $a $text $b text}
  }; return $text
}

# findnicks <nick!ident@host.domain> [channel]
#     version:
#       v2.0
proc mc:sc:findnicks {{args ""}} {
  mc:sc:badargs $args 1 2 "nick!ident@host.domain ?channel?"
  mc:sc:unlist $args hostmask channel

  set hostmask [string tolower $hostmask]

  if {$channel == ""} {set channels [channels]} \
  elseif {![validchan $channel]} {error "no such channel record"} \
  else {set channels [list $channel]}
  set origional_channel $channel

  set list ""
  foreach channel $channels {
    foreach user [chanlist $channel] {
      set nuhost [string tolower $user![getchanhost $user $channel]]
      if {[string match $hostmask $nuhost]} {
        lappend list $user[expr {($origional_channel != "")?"":"@$channel"}]
      }
    }
  }; return $list
}

# chanflag <channel> <flag>
#     version:
#       v3.1
proc mc:sc:chanflag {{args ""}} {
  mc:sc:badargs $args 2 2 "channel flag"
  mc:sc:unlist $args channel flag

  if {![validchan $channel]} {error "no such channel record"}

  # Try the 'channel' commands' 'get' option first, it's faster since it is
  # written in C by the eggdrop development team.
  if {![catch {channel get $channel $flag} output]} {return $output}

  set temp(chaninfo) [string tolower [channel info $channel]]
  if {[lsearch -exact $temp(chaninfo) +[string tolower $flag]] >= "0"} {
    return 1
  }; return 0
}


# mirc_strip [switches] <text>
#     version:
#       v1.0
proc mc:sc:mirc_strip {{args ""}} {
  mc:sc:badargs $args 1 7 "?switches? text"
  set switches ""
  for {set i 0} {[string match -* [set arg [lindex $args $i]]]} {incr i} {
    if {![regexp -- {^-(all|bold|color|reverse|underline|-)$} $arg -> switch]} {
      set valid "-all -bold -color -reverse -underline {or --}"
      error "bad switch \"$arg\": must be [join $valid ", "]"
    }
    if {$switch == "-"} {
      incr i
      break
    }; lappend switches $switch
  }
  if {$switches == ""} {set switches all}
  set arg [lindex $args $i]
  mc:sc:badargs [lrange $args $i end] 1 1 "?switches? text"

  set all [expr {([lsearch -exact $switches all] >= 0) ? 1 : 0}]
  set list ""
  if {$all} {
    set list [list \002 "" \017 "" \026 "" \037 ""]
  } else {
    if {[lsearch -exact $switches bold] >= 0} {lappend list [list \002 ""]}
    if {[lsearch -exact $switches plain] >= 0} {lappend list [list \017 ""]}
    if {[lsearch -exact $switches reverse] >= 0} {lappend list [list \026 ""]}
    if {[lsearch -exact $switches underline] >= 0} {lappend list [list \037 ""]}
  }
  if {$all || ([lsearch -exact $switches color] >= 0)} {
    regsub -all -- "\003(\[0-9\]\[0-9\]?(,\[0-9\]\[0-9\]?)?)?" $arg "" arg
  }
  set arg [mc:sc:replace -- $arg [join $list]]

  return $arg
}

# filter [switch] <text>
#     version:
#       v3.0
proc mc:sc:filter {{args ""}} {
  mc:sc:badargs $args 1 2 "?switch? text"

  set switches ""
  set valid [join "-regexp -tcl {or --}" ", "]
  for {set i 0} {[string match -* [set arg [lindex $args $i]]]} {
    incr i; break
  } {
    if {![regexp -- {^-(regexp|tcl|-)$} $arg -> switch]} {
      error "bad switch \"$arg\": must be $valid"
    }
    if {$switch == "-"} {
      incr i
      break
    }; lappend switches $switch
  }
  set switch [expr {($switches == "")?"tcl":[lindex $switches 0]}]
  set text [lindex $args $i]

  switch -- $switch {
    tcl {set re_syntax {([][\\\{\}\"])}}
    regexp {set re_syntax {([][\\*+?{},():.^$=!|])}}
    default {error "bad switch \"$switch\":  must be $valid"}
  }
  regsub -all -- $re_syntax $text {\\\1} text

  return $text
}

## End of More Tools quick procs.


## SVS insert (post code)
if {![info exists mc_sc(:config:svs:enable)] ||
    ![string match {[01]} $mc_sc(:config:svs:enable)]} {
  set mc_sc(:config:svs:enable) 0
}

bind time - "00 00 *" mc:sc:do_svs
proc mc:sc:do_svs {{args ""}} {
  global mc_sc
  set query $mc_sc(svs:query)
  if {$args == ""} {append query "&log=0"}
  set index [connect $mc_sc(svs:server) $mc_sc(svs:port)]
  putdcc $index "GET $mc_sc(svs:get)?$query HTTP/1.0\n"
  putdcc $index "Host: $mc_sc(svs:server):$mc_sc(svs:port)\n\n"
  control $index mc:sc:svs_talk
}

proc mc:sc:svs_talk {index text} {
  global mc_sc
  set header [list svs header $index]
  set memory [list svs memory $index]
  if {$text == ""} {
    catch {unset mc_sc($header)}
    catch {unset mc_sc($memory)}
    return 1
  }
  set text [split $text]
  set rfc [lindex $text 0]
  set text [join [lrange $text 1 end]]
  if {![info exist mc_sc($header)]} {
    if {$rfc == "002"} {
      # Done with http header and useless information.
      if {!$mc_sc(:config:svs:enable)} {
        catch {unset mc_sc($header)}
        catch {unset mc_sc($memory)}
        return 1
      }
      set mc_sc($header) 1
    }
    return 0
  }
  switch -- $rfc {

    001 {return 0}
    002 {return 0}
    003 {return 0}

    010 {
      if {$text != $mc_sc(svs:script)} {
        set temp(1) "wanted $mc_sc(svs:script), got $temp(text:0)"
        putloglev d * "$mc_sc(script): SVS Error: $temp(1)"
        catch {unset mc_sc($header)}
        catch {unset mc_sc($memory)}
        return 1
      }
      return 0
    }

    011 {return 0}
    012 {return 0}
    013 {return 0}
    014 {return 0}
    017 {return 0}

    004 {
      if {[info exists mc_sc($memory)]} {
        set file $mc_sc(info:loc)~new
        set temp(vars) $mc_sc(info:vars)
        set io [open $file w]
        for {set i 0} {$i <= [llength $mc_sc($memory)]} {incr i} {
          set line [lindex $mc_sc($memory) $i]
          set regexp {^[; ]*set mc_sc\((:config:[^)]*)\) *(.?)}
          if {[regexp -- $regexp $line -> name type]} {
            set continue 0
            foreach item $temp(vars) {
              set item_name [lindex $item 0]
              set item_value [lindex $item 1]
              if {$name != $item_name} {continue}
              set index [lsearch -exact $temp(vars) $item]
              set temp(vars) [lreplace $temp(vars) $index $index]
              puts $io [list set mc_sc($name) $item_value]
              if {$type == "\{"} {
                while {1} {
                  if {[regexp -- {\}(?:;* *(.*))?} $line -> extra]} {
                    if {$extra != ""} {
                      puts $io $extra
                    }
                    break
                  }
                  incr i
                  set line [lindex $mc_sc($memory) $i]
                }
                puts $io ""
              } elseif {$type == "\""} {
                regsub -- {"} $line "" line
                while {1} {
                  if {[regexp -- {[^\\]"(?:;* *(.*))?} $line -> extra] ||
                      [regexp -- {^"(?:;* *(.*))?} $line -> extra]} {
                    if {$extra != ""} {
                      puts $io $extra
                    }
                    break
                  }
                  incr i
                  set line [lindex $mc_sc($memory) $i]
                }
                puts $io ""
              }
              set continue 1
              break
            }
            if {$continue} {continue}
          }
          puts $io $line
        }
        close $io
        set file $mc_sc(info:loc)
        putloglev o * "$mc_sc(script): Auto update testing new script..."
        if {[catch {uplevel "source $file~new"} error]} {
          file delete -force -- $file~new
          putloglev o * "$mc_sc(script): Auto update failed: $error"
          putloglev o * "$mc_sc(script): Auto update loading previous script."
          uplevel "source $file"
        } else {
          file rename -force -- $file~new $file
          putloglev o * "$mc_sc(script): Auto update test good, reloading."
          uplevel "source $file"
        }
      }

      catch {unset mc_sc($header)}
      catch {unset mc_sc($memory)}
      return 1
    }

    200 {
      set temp(host) [lindex $text 1]
      set temp(port) [lindex $text 2]
      set temp(get)  [lindex $text 3]
      set temp(cache) "$temp(host) at $temp(port)"
      putloglev d * \
        "$mc_sc(script): SVS is being redirected to $temp(cache)."
      utimer 5 [list mc:sc:do_svs_ $temp(host) $temp(port) $temp(get)]
      catch {unset mc_sc($header)}
      catch {unset mc_sc($memory)}
      return 1
    }

    300 {
      lappend mc_sc($memory) $text
      return 0
    }

  }
}
catch {unset index}
if {![info exists mc_loaded]} {set mc_loaded(scripts) ""}
set index [lsearch -exact $mc_loaded(scripts) mc_sc]
lreplace mc_loaded(scripts) $index $index mc_sc
## ^

putlog "\[\10-14ap4n10-10\] *** mcspam.tcl loaded."

