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.

Protect Ops not acting correct on ban set on protected user

Support & discussion of released scripts, and announcements of new releases.
Post Reply
K
Kraka
Voice
Posts: 19
Joined: Thu Apr 21, 2005 9:25 pm

Protect Ops not acting correct on ban set on protected user

Post by Kraka »

Im currently having a problem with this script when a user sets a ban on a bot. All that it will do is deop the user and remove their flags. It will not set a ban on the user. The other two actions of kicking a user and deoping a user work correctly with setting a ban on the user, but just not one if they set a ban on a protected user. any help would be great.

Code: Select all

##
# Protect Ops v2.0.6
#  by MC_8 - Carl M. Gregory <mc8@purehype.net>
#  This script will only run on eggdrop 1.6.14 or greater.
#
#    R.I.P. Mom, To always be remembered; Nancy Marie Gregory.
#
# My Website - http://mc.purehype.net/
# Have a bug or script not working correctly?
#   http://mc.purehype.net/bugzilla/
# Have a question?
#   http://forum.purehype.net/viewforum.php?f=5
##

##
# Description
##
# This script basically does what 'chanset''s 'protectops' and 'dontkickops'
# does, but with more options and customized reactions.  A "super protectops" as
# someone called it, wording in relation to slennox's script "super bitch".
#
# This can also be setup to protect others, not just op's.
##

##
# Commands
##
# DCC:
#
#   chanset <channel> <+/->mc.protect_ops
#     This will enable (+) or disable (-) the script for the specific
#     channel.
##

##
# Configuration
##
#

## Kick protection settings.

# What op'd users do you want to protect from op kick's?  If you want to protect
# every op that is currently op'd, regardless if there a registered op in the
# bot, then set this to "-|-".  Set this to "" to disable kick protection.  Flag
# syntax, <global>|<channel>
set mc_po(:config:kick:protect) "NBn|N"

# What do you want to do upon other op kicking an op?  Separate each command
# with a new line.
# Valid commands are:
#   /msg <nick|channel> <text>
#   /notice <nick|channel> <text>
#   /ban <channel> <nick> [time [reason]]
#     If time is specified;
#        0 = Perm ban.
#        Any number greater than 0 is the ban expiration in min's.
#     If the number is greater than 0, the reason will be put into the
#     bot's internal banlist record as the reason for adding the ban.  Otherwise
#     the ban is considered a server ban and reason is just ignored.  Also, if
#     you want the ban to be "sticky" (read up on '.help stick') then append the
#     time with an '!' (exclamation point).
#   /kick <channel> <nick>
#   /deop <channel> <nick>
#   /raw <raw_irc_code>
#     See: http://www.user-com.undernet.org/documents/rfc1459.txt
#   /chattr <handle> <flag changes> [channel]
#     This acts exactly the same way as a '.chattr' in the DCC console, see
#     '.help chattr'.
#   /note <handle> <text>
#     Sends an internal note via the notes module to <handle>.
#   /flagnote <flag [channel]> <text>
#     Sends an internal note via the notes module to all whom match the
#     specified flag(s).  Flag format is global|channel.
# Valid replacement variables are;
#   %botnick       - The bot's IRC nickname.
#   %channel       - The channel the action took place in.
#   %reason        - The reason specified for the action.
#   %nick          - The IRC nickname that performed the action.
#   %ident         - The ident of the IRC nickname that performed the action.
#   %host          - The host of the IRC nickname that performed the action.
#   %handle        - The handle of the IRC nickname that performed the action.
#   %victim_nick   - The IRC nickname of the victim.
#   %victim_ident  - The ident of the victim.
#   %victim_host   - The host of the victim.
#   %victim_handle - The handle of the victim.
set mc_po(:config:kick:do) {
  /deop %channel %nick
  /ban %channel %nick [1440 [don't kick a protected op]]
  /chattr %handle -mtfo|-mtfo %channel
  /msg %nick You just kicked %victim_nick, that's a protected op!
  /note eggie %nick Kicked %victim_nick on %channel his ident is %ident
}


## Ban protection settings.

# What op'd users do you want to protect from op ban's?  If you want to protect
# every op that is currently op'd, regardless if there a registered op in the
# bot, then set this to "-|-".  Set this to "" to disable ban protection.  Flag
# syntax: <global>|<channel>
set mc_po(:config:ban:protect) "NnB|N"

# What do you want to do upon other op banning an op?  Separate each command
# with a new line.
# Valid commands are:
#   /msg <nick|channel> <text>
#   /notice <nick|channel> <text>
#   /ban <channel> <nick> [time [reason]]
#     If time is specified;
#        0 = Perm ban.
#        Any number greater than 0 is the ban expiration in min's.
#     If the number is greater than 0, the reason will be put into the
#     bot's internal banlist record as the reason for adding the ban.  Otherwise
#     the ban is considered a server ban and reason is just ignored.  Also, if
#     you want the ban to be "sticky" (read up on '.help stick') then append the
#     time with an '!' (exclamation point).
#   /kick <channel> <nick>
#   /deop <channel> <nick>
#   /raw <raw_irc_code>
#     See: http://www.user-com.undernet.org/documents/rfc1459.txt
#   /chattr <handle> <flag changes> [channel]
#     This acts exactly the same way as a '.chattr' in the DCC console, see
#     '.help chattr'.
#   /note <handle> <text>
#     Sends an internal note via the notes module to <handle>.
#   /flagnote <flag [channel]> <text>
#     Sends an internal note via the notes module to all whom match the
#     specified flag(s).  Flag format is global|channel.
#   /reverse [option]
#     Removes the ban set.  If option is set to 'valid_only', it will only
#     reverse the ban if the user that matches the ban is a valid op (registered
#     with the bot and has the 'o' flag).
# Valid replacement variables are;
#   %botnick       - The bot's IRC nickname.
#   %channel       - The channel the action took place in.
#   %nick          - The IRC nickname that performed the action.
#   %ident         - The ident of the IRC nickname that performed the action.
#   %host          - The host of the IRC nickname that performed the action.
#   %handle        - The handle of the IRC nickname that performed the action.
#   %victim_nick   - The IRC nickname of the victim.
#   %victim_ident  - The ident of the victim.
#   %victim_host   - The host of the victim.
#   %victim_handle - The handle of the victim.
#   %banmask       - The banmask that triggered this.
set mc_po(:config:ban:do) {
  /chattr %handle -mtfo|-mtfo %channel
  /deop %channel %nick
  /chattr %handle -mtfo|-mtfo %channel
  /msg %nick You just banned %victim_nick, that's an op!
  /reverse valid_only
  /note eggie %nick did a ban on %victim_nick on %channel his ident is %ident
  /ban %channel %nick [1440 [don't kick a protected op]]
}


## Deop protection settings.

# What op'd users do you want to protect from op deop's?  If you want to protect
# every op that is currently op'd, regardless if there a registered op in the
# bot, then set this to "-|-".  Set this to "" to disable deop protection.  Flag
# syntax: <global>|<channel>
set mc_po(:config:deop:protect) "NnB|N"

# What do you want to do upon other op deopping an op?  Separate each command
# with a new line.
# Valid commands are:
#   /msg <nick|channel> <text>
#   /notice <nick|channel> <text>
#   /ban <channel> <nick> [time [reason]]
#     If time is specified;
#        0 = Perm ban.
#        Any number greater than 0 is the ban expiration in min's.
#     If the number is greater than 0, the reason will be put into the
#     bot's internal banlist record as the reason for adding the ban.  Otherwise
#     the ban is considered a server ban and reason is just ignored.  Also, if
#     you want the ban to be "sticky" (read up on '.help stick') then append the
#     time with an '!' (exclamation point).
#   /kick <channel> <nick>
#   /deop <channel> <nick>
#   /raw <raw_irc_code>
#     See: http://www.user-com.undernet.org/documents/rfc1459.txt
#   /chattr <handle> <flag changes> [channel]
#     This acts exactly the same way as a '.chattr' in the DCC console, see
#     '.help chattr'.
#   /note <handle> <text>
#     Sends an internal note via the notes module to <handle>.
#   /flagnote <flag [channel]> <text>
#     Sends an internal note via the notes module to all whom match the
#     specified flag(s).  Flag format is global|channel.
#   /reverse [option]
#     Re-ops the victim.  If option is set to 'valid_only', it will only reverse
#     the op status if the user is a valid op (registered with the bot and has
#     the 'o' flag).
# Valid replacement variables are;
#   %botnick       - The bot's IRC nickname.
#   %channel       - The channel the action took place in.
#   %nick          - The IRC nickname that performed the action.
#   %ident         - The ident of the IRC nickname that performed the action.
#   %host          - The host of the IRC nickname that performed the action.
#   %handle        - The handle of the IRC nickname that performed the action.
#   %victim_nick   - The IRC nickname of the victim.
#   %victim_ident  - The ident of the victim.
#   %victim_host   - The host of the victim.
#   %victim_handle - The handle of the victim.
set mc_po(:config:deop:do) {
  /deop %channel %nick
  /ban %channel %nick [1440 [don't deop a protected op]]
  /chattr %handle -mtfo|-mtfo %channel
  /msg %nick You just deopped %victim_nick, that's an op!
  /reverse valid_only
  /note eggie %nick deop %victim_nick on %channel his ident is %ident
}


## Miscellaneous settings.

# What flagged users do you want to exempt from this script?  Set to "" to exempt
# no one.
set mc_po(:config:exempt) "b|"

# What other flagged users do you want to protect as well?  This is useful if
# the matching flagged user is not op'd, the script will still protect him/her.
# Set this to "" to disable.  Flag syntax: <global>|<channel>
set mc_po(:config:also:protect) ""

# [0=no/1=yes] If the bot is not opped, do you want to perform the *:do command
# setup above?  In respects to /msg, /notice, /ban, and /kick -- with proper
# respects to the channels (/msg and /notice being the channel the action took
# place in -- the others being the channels specified).
set mc_po(:config:bigtalker) 1

# How do you want to mask hosts?  This is used for banning and adding
# a user to the userfile (if either enabled).
#         0 - *!user@host.domain
#         1 - *!*user@host.domain
#         2 - *!*@host.domain
#         3 - *!*user@*.domain
#         4 - *!*@*.domain
#         5 - nick!user@host.domain
#         6 - nick!*user@host.domain
#         7 - nick!*@host.domain
#         8 - nick!*user@*.domain
#         9 - nick!*@*.domain
#       You can also specify a type of 10-19 which corresponds to types 0-9,
#       using this sub rule;  If host.domain is a(n)-
#         name - Instead of using a * wildcard to replace portions of the
#                host.domain, it replaces the numbers in the host.domain with a
#                '?' (question mark) wildcard.
#         ip   - It will mask as normal, with no '?' (question mark)
#                replacements as does hostname.
set mc_po(:config:maskhostbytype) 3

## SVS Client (Script Version Service) v4.1.2 ##
# Once a day, the SVS Client will connect to MC_8's SVS Server to determine if
# there is a newer version of this script available.  If a newer version is
# found, the script will be auto updated.

# [0=no/1=yes] Do you want to enable auto updating?  If you chose to disable
# auto updating, it will not automatically update the script upon finding a
# newer version.
set mc_po(:config:svs:enable) 0 

#
##

##
# Done with configurations, do not edit past here unless you know TCL.
##
#

## SVS insert (pre code)
#Script:mc_po
catch {unset temp}

foreach temp(bind) [binds mc:po:*] {
  foreach {temp(1) temp(2) temp(3) temp(4) temp(5)} $temp(bind) break
  catch {unbind $temp(1) $temp(2) $temp(3) $temp(5)}
}

set mc_po(info:vars) ""
foreach {temp(name) temp(value)} [array get mc_po :config:*] {
  lappend mc_po(info:vars) [list $temp(name) $temp(value)]
}
set mc_po(info:loc) [info script]
array set mc_po [list \
  script                 "Protect Ops" \
  version                "v2.0.6" \
  svs:script             "protectops" \
  svs:version            "002000006000" \
  svs:client_version     "v4.1.2" \
  svs:client_svs_version "004001002000" \
  svs:server             "mc.svs.purehype.net" \
  svs:port               "80" \
  svs:get                "/index.tcl"]
set mc_po(svs:query)    "svs=$mc_po(svs:script)&"
append mc_po(svs:query) "version=$mc_po(svs:version)&"
append mc_po(svs:query) \
  "svs_version=$mc_po(svs:client_svs_version)"

if {![info exists numversion] || 
    ([string range $numversion 0 4] < "10614") ||
    (([string range $numversion 0 4] == "10614") &&
     ([string range $numversion 5 6] != "00"))} {
  set temp(tag) "$mc_po(script) $mc_po(version)"
  putloglev o * \
    "$temp(tag) by MC_8 will only work on eggdrop 1.6.14 (stable) or greater."
  putloglev o * "$temp(tag) will not work with eggdrop $version."
  putloglev o * "$temp(tag) not loaded."
  uplevel #0 {
    if {[info exists temp] && ![array exists temp]} {unset temp}
    set temp(svs_return) [list 0 "Need to upgrade eggdrop."]
  }; return 1
}
## ^

setudef flag mc.protect_ops

# Error Catching System (ECS), v4.1.
proc mc:po:errchk {command args} {
  
  # Enable (1) or disable (0) auto reporting of bugs to mc8@purehype.net.
  # This setting here for those who want to disable it in fear of privacy
  # violations.
  set enable_auto_reporting 0
  
  if {![info exists ::lastCommand]} {set ::lastCommand [list]}
  set ::lastCommand \
    "[list [list [clock seconds] $command $args]] $::lastCommand"
  set ::lastCommand [lrange $::lastCommand 0 4]
  if {![catch {eval $command $args} return]} {return $return}
  if {$::errorCode == "mc.ecs.done"} {return -errorcode mc.ecs.done -code error}
  
  set temp(lastbind) [expr {[info exists ::lastbind]?$::lastbind:"-NULL-"}]
  set temp(eversion) [expr {[info exists ::version]?$::version:"-NULL-"}]
  set message "
    ************************************
    (ECS 4.1) Error found in TCL script.
    --------------
    Script name   : $::mc_po(script)
    Script version: $::mc_po(version)
    Egg. Version  : $temp(eversion)
    TCL Version   : [info tclversion] ([info patchlevel])
    --------------
    Last Bind     : $temp(lastbind)
    Last Commands :"
  foreach line $::lastCommand {
    foreach {time command arg} $line break
    append message "\n        ${time}- $command $arg"
  }
  append message "\n    Error stack   :"
  foreach line [split $::errorInfo \n] {
    append message "\n        $line"
  }
  append message "\n    --------------"
  
  set message [lrange [split $message \n] 1 end]
  set offset [string first * [lindex $message 0]]
  set new_message [list]
  foreach line $message {lappend new_message [string range $line $offset end]}
  set message $new_message
  
  if {!$enable_auto_reporting ||
      [catch {socket -async mc.purehype.net 80} sid]} {
    foreach line $message {putloglev o * $line}
    putloglev o * "Submit this bug to http://mc.purehype.net/bugzilla/ . If"
    putloglev o * "you are experiencing problems with bugzilla, contact MC_8"
    putloglev o * "via email at mc8@purehype.net. Please include all"
    putloglev o * "information shown here, in this ECS report."
    putloglev o * "************************************"
    return -errorcode mc.ecs.done -code error
  }
  fconfigure $sid -blocking 0 -buffering line

  set query [list]
  # This info is passed should I need to hunt down the bot's owner for more
  # information.
  lappend query "Admin   : [expr {[info exists ::admin]?$::admin:""}]"
  lappend query "Owner   : [expr {[info exists ::owner]?$::owner:""}]"
  lappend query "Botnick : [expr {[info exists ::botnick]?$::botnick:""}]"
  lappend query "Server  : [expr {[info exists ::server]?$::server:""}]"
  lappend query "Channels: [join [lsort -dictionary [channels]] ", "]"
  lappend query ""
  
  foreach line $message {lappend query $line}
  lappend query "************************************"
  
  set new_query [list]
  foreach line $query {
    regsub -all -- "(\002|\017|\026|\037)" $line "" line
    regsub -all -- "\003(\[0-9\]\[0-9\]?(,\[0-9\]\[0-9\]?)?)?" $line "" line
    regsub -all {\%} $line "%25" line
    set i [string length $line]
    while {[regexp {[^a-zA-Z0-9%]} $line toh] && ($i >= 0)} {
      scan "$toh" %c dec
      regsub -all -- "\\${toh}" $line "%[format %X $dec]" line
      incr i -1
    }; lappend new_query $line
  }; set query $new_query
  
  set query "message=[join $query %0a]"
  puts $sid "POST /report_bug.tcl HTTP/1.0\
           \nHost: mc.purehype.net:80\
           \nContent-type: application/x-www-form-urlencoded\
           \nContent-Length: [expr [string length $query] +2]"
  puts $sid \n$query
  close $sid

  foreach line $message {putloglev o * $line}
  putloglev o * "Automatically sending bug report to MC_8."
  putloglev o * "If you have a firewall setup, it may block the sending of this"
  putloglev o * "report. You can check the status of your bug, as soon as MC_8"
  putloglev o * "adds it, at http://mc.purehype.net/bugzilla/ ."
  putloglev o * "************************************"
  
  return -errorcode mc.ecs.done -code error
}
# ^

bind join - * mc:po:bind:join
proc mc:po:bind:join {nick uhost handle channel} {
  return [mc:po:errchk mc:po:bind:join_ $nick $uhost $handle $channel]
}
proc mc:po:bind:join_ {nick uhost handle channel} {
  if {![isbotnick $nick]} {mc:po:list ial add $nick $uhost $channel}
}

bind raw - 315 mc:po:bind:raw
proc mc:po:bind:raw {from keyword arg} {
  return [mc:po:errchk mc:po:bind:raw_ $from $keyword $arg]
}
proc mc:po:bind:raw_ {from keyword arg} {
  set channel [lindex [split $arg] 1]
  if {![validchan $channel]} {return 0}
  mc:po:list ial remove "" $channel
  foreach temp(user) [chanlist $channel] {
    if {[isbotnick $temp(user)]} {continue}
    mc:po:list ial add $temp(user) [getchanhost $temp(user) $channel] $channel
  }
  return 0
}

bind part - * mc:po:bind:part
proc mc:po:bind:part {nick uhost handle channel text} {
  return [mc:po:errchk mc:po:bind:part_ $nick $uhost $handle $channel $text]
}
proc mc:po:bind:part_ {nick uhost handle channel text} {
  if {[isbotnick $nick]} {mc:po:list ial remove "" $channel} \
  else {mc:po:list ial schedule_remove $nick $channel 30}
}

bind sign - * mc:po:bind:sign
proc mc:po:bind:sign {nick uhost handle channel reason} {
  return [mc:po:errchk mc:po:bind:sign_ $nick $uhost $handle $channel $reason]
}
proc mc:po:bind:sign_ {nick uhost handle channel reason} {
  if {[isbotnick $nick]} {mc:po:list ial remove "" $channel} \
  else {mc:po:list ial schedule_remove $nick $channel 30}
}

bind kick - * mc:po:bind:kick
proc mc:po:bind:kick {nick uhost handle channel target reason} {
  return [mc:po:errchk mc:po:bind:kick_ \
    $nick $uhost $handle $channel $target $reason]
}
proc mc:po:bind:kick_ {nick uhost handle channel target reason} {
  if {[isbotnick $target]} {mc:po:list ial remove "" $channel} \
  elseif {$nick == $target} {mc:po:list ial schedule_remove $nick $channel 30} \
  else {
    mc:po:list eval $nick $channel kick $target $reason
    mc:po:list ial schedule_remove $target $channel 30
  }
}

bind mode - * mc:po:bind:mode
proc mc:po:bind:mode {nick uhost handle channel mode victim} {
  return [mc:po:errchk mc:po:bind:mode_ \
    $nick $uhost $handle $channel $mode $victim]
}
proc mc:po:bind:mode_ {nick uhost handle channel mode victim} {
  if {[isbotnick $nick] || ($nick == "")} {return 0}
  switch -- $mode {
    "+b" {
      foreach temp(user) [mc:po:list ial find $channel $victim] {
        set temp(nick) [lindex $temp(user) 0]
        if {$temp(nick) == $nick} {continue}
        set temp() [mc:po:list eval $nick $channel ban $temp(nick) \
          [lindex $temp(user) 1] $victim]
        if {$temp() == "1"} {
          # Action taken.
          break
        }
      }
    }
    "-o" {
      if {$victim != $nick} {mc:po:list eval $nick $channel deop $victim}
    }
  }
}

bind nick - * mc:po:bind:nick
proc mc:po:bind:nick {nick uhost handle channel newnick} {
  return [mc:po:errchk mc:po:bind:nick_ $nick $uhost $handle $channel $newnick]
}
proc mc:po:bind:nick_ {nick uhost handle channel newnick} {
  if {![isbotnick $newnick]} {
    mc:po:list ial remove $nick $channel
    mc:po:list ial add $newnick $uhost $channel
  }
}


proc mc:po:list {command {args ""}} {
  return [mc:po:errchk mc:po:list_ $command $args]
}
proc mc:po:list_ {command arg} {
  set args $arg
  global mc_po
  switch -- $command {

    "ial" {
      # Ial format; nick uhost channel
      if {![info exists mc_po(:ial:)]} {set mc_po(:ial:) ""}
      set temp(command) [lindex $args 0]
      set args [lrange $args 1 end]
      switch -- $temp(command) {

        "add" {
          # mc:po:list ial add <nick> <uhost> <channel>
          foreach {nick uhost channel} $args break
          mc:po:list ial remove $nick $channel
          lappend mc_po(:ial:) [list $nick $uhost $channel]
        }

        "remove" {
          # mc:po:list ial remove [nick] [channel]
          set nick ""; set channel ""
          foreach {nick channel} $args break

          set temp(new_list) ""
          foreach temp(entry) [mc:po:list ial list] {
            set temp(nick) [string tolower [lindex $temp(entry) 0]]
            set temp(channel) [string tolower [lindex $temp(entry) 2]]
            if {(($nick == "") || ($temp(nick) == [string tolower $nick])) &&
                (($channel == "") ||
                 ($temp(channel) == [string tolower $channel]))} {
              mc:po:list ial kill_schedule $temp(nick) $temp(channel)
              continue
            }
            lappend temp(new_list) $temp(entry)
          }
          set mc_po(:ial:) $temp(new_list)
        }

        "find" {
          # mc:po:list ial find <channel> <nick!user@host*>
          foreach {channel nuhost_masked} $args break
          set nuhost_masked [string tolower $nuhost_masked]

          set temp(return) ""
          foreach temp(entry) [mc:po:list ial list $channel] {
            set temp(nick) [string tolower [lindex $temp(entry) 0]]
            set temp(uhost) [string tolower [lindex $temp(entry) 1]]
            if {[string match $nuhost_masked $temp(nick)!$temp(uhost)]} {
              lappend temp(return) [lrange $temp(entry) 0 1]
            }
          }
          return $temp(return)
        }

        "list" {
          # mc:po:list ial list [channel]
          set channel ""
          foreach channel $args break

          if {$channel == ""} {return $mc_po(:ial:)}

          set temp(return) ""
          foreach temp(entry) $mc_po(:ial:) {
            set temp(channel) [string tolower [lindex $temp(entry) 2]]
            if {$temp(channel) == [string tolower $channel]} {
              lappend temp(return) $temp(entry)
            }
          }
          return $temp(return)
        }

        "schedule_remove" {
          # mc:po:list ial schedule_remove <nick> <channel> <seconds>
          foreach {nick channel time} $args break
          set nick [string tolower $nick]
          set channel [string tolower $channel]

          set temp(list) [list mc:po:list remove $nick $channel]

          foreach temp(utimer) [utimers] {
            if {[lsearch -exact $temp(utimer) $temp(list)] == "1"} {
              return 0
            }
          }

          utimer $time $temp(list)
        }

        "kill_schedule" {
          # mc:po:list ial kill_schedule <nick> <channel>
          foreach {nick channel} $args break
          set nick [string tolower $nick]
          set channel [string tolower $channel]

          set temp(list) [list mc:po:list remove $nick $channel]

          foreach temp(utimer) [utimers] {
            if {[lsearch -exact $temp(utimer) $temp(list)] == "1"} {
              killutimer [lindex $temp(utimer) 2]
              break
            }
          }
        }

      }
    }

    "is_protected" {
      # mc:po:list is_protected <nick> <handle> <channel> <type> \
      #   <punisher_handle>
      foreach {nick handle channel type punisher_handle} $args break
      global botnet-nick

      if {
        ([channel get $channel mc.protect_ops]) &&
        ((($nick != "") && ([onchan $nick $channel])) ||
         ($nick == "")) &&
        ($punisher_handle != ${botnet-nick}) &&
        ((($mc_po(:config:${type}:protect) == "-|-") &&
          ((($type == "deop") && ([wasop $nick $channel])) ||
           ((($type == "kick") || ($type == "ban")) &&
            ([isop $nick $channel])))) ||
         (($mc_po(:config:${type}:protect) != "") &&
          ([matchattr $handle $mc_po(:config:${type}:protect) $channel])) ||
         (($mc_po(:config:also:protect) != "") &&
          ([matchattr $handle $mc_po(:config:also:protect) $channel]))) &&
        (($mc_po(:config:exempt) != "") &&
         (![matchattr $punisher_handle $mc_po(:config:exempt) $channel]))
      } {return 1} else {return 0}
    }

    "eval" {
      # mc:po:list eval <nick> <channel> kick <target_nick> [reason]
      # mc:po:list eval <nick> <channel> deop <target_nick>
      # mc:po:list eval <nick> <channel> ban  <target_nick> <target_uhost> \
      #   <banmask>
      global botnick botnet-nick
      set reason ""; set banmask ""
      foreach {nick channel type target_nick reason banmask} $args break

      if {($nick != "") && ([set uhost [getchanhost $nick]] != "")} {
        regexp -- {^(.*)@(.*)$} $uhost -> ident host
        set handle [nick2hand $nick]
      } else {
        set ident ""
        set host ""
        set handle ""
      }

      if {$type == "ban"} {
        regexp -- {^(.*)@(.*)$} $reason -> target_ident target_host
        set target_handle [finduser $target_nick!$reason]
        set reason ""
      } else {
        regexp -- {^(.*)@(.*)$} [getchanhost $target_nick $channel] -> \
          target_ident target_host
        set target_handle [nick2hand $target_nick $channel]
      }

      if {
   ![mc:po:list is_protected $target_nick $target_handle $channel $type $handle]
      } {return 0}

      set temp(return_number) 1

      set temp(do) [mc:po:replace -- $mc_po(:config:${type}:do) [list \
        %botnick       $botnick      \
        %channel       $channel      \
        %reason        $reason       \
        %nick          $nick         \
        %ident         $ident        \
        %host          $host         \
        %handle        $handle       \
        %victim_nick   $target_nick  \
        %victim_ident  $target_ident \
        %victim_host   $target_host  \
        %victim_handle $target_handle\
        %banmask       $banmask]]
      foreach temp(command) [split $temp(do) \n] {
        set temp(command) [string trim $temp(command) " \t"]
        if {$temp(command) == ""} {continue}
        set temp(command) [split $temp(command)]
        set temp(args) [lrange $temp(command) 1 end]
        set temp(command) [string tolower [lindex $temp(command) 0]]
        switch -- $temp(command) {
          "/msg" {
            if {![botisop $channel] && !$mc_po(:config:bigtalker)} {continue}

            set temp(to) [lindex $temp(args) 0]
            if {$temp(to) == ""} {continue} ;# Server action?
            putserv "PRIVMSG $temp(to) :[join [lrange $temp(args) 1 end]]"
          }
          "/notice" {
            if {![botisop $channel] && !$mc_po(:config:bigtalker)} {continue}

            set temp(to) [lindex $temp(args) 0]
            if {$temp(to) == ""} {continue} ;# Server action?
            putserv "NOTICE $temp(to) :[join [lrange $temp(args) 1 end]]"
           }
          "/ban" {
            foreach {temp(channel) temp(nick) temp(time) temp(reason)} \
              $temp(args) break

            if {$temp(nick) == ""} {continue} ;# Server action?

            if {![validchan $temp(channel)]} {
              set temp() "$temp(command) [join $temp(args)]"
              putloglev o * "$mc_po(script): Invalid channel; $temp()"
              continue
            }

            if {![onchan $temp(nick) $temp(channel)]} {
              set temp() "$temp(command) [join $temp(args)]"
              putloglev o * "$mc_po(script): Nickname not on channel; $temp()"
              continue
            }

            if {![botisop $temp(channel)] && !$mc_po(:config:bigtalker)} {
              continue
            }

            set temp(banmask) [mc:po:maskhostbytype \
              $temp(nick)![getchanhost $temp(nick)] \
              $mc_po(:config:maskhostbytype)]

            if {$temp(time) == ""} {
              putserv "MODE $temp(channel) +b $temp(banmask)"
              continue
            }

            set temp(sticky) [string match *! $temp(time)]
            regexp -- {^(.*)!?$} $temp(time) -> temp(time)

            if {[regexp -- {[^0-9]} $temp(time)]} {
              set temp() "$temp(command) [join $temp(args)]"
              putloglev o * "$mc_po(script): Invalid time format; $temp()"
              continue
            }

            newchanban $temp(channel) $temp(banmask) ${botnet-nick} $reason \
              $temp(time) [expr {$temp(sticky)?"sticky":"none"}]
           }
          "/kick" {
            set temp(channel) [lindex $temp(args) 0]
            set temp(nick) [lindex $temp(args) 1]

            if {![validchan $temp(channel)]} {
              set temp() "$temp(command) [join $temp(args)]"
              putloglev o * "$mc_po(script): Invalid channel; $temp()"
              continue
            }

            if {![onchan $temp(nick) $temp(channel)]} {
              set temp() "$temp(command) [join $temp(args)]"
              putloglev o * "$mc_po(script): Nickname not on channel; $temp()"
              continue
            }

            if {![botisop $temp(channel)] && !$mc_po(:config:bigtalker)} {
              continue
            }

            putserv "KICK $temp(channel) $temp(nick) :$reason"
          }
          "/deop" {
            set temp(channel) [lindex $temp(args) 0]
            set temp(nick) [lindex $temp(args) 1]

            if {![validchan $temp(channel)]} {
              set temp() "$temp(command) [join $temp(args)]"
              putloglev o * "$mc_po(script): Invalid channel; $temp()"
              continue
            }

            if {![onchan $temp(nick) $temp(channel)]} {
              set temp() "$temp(command) [join $temp(args)]"
              putloglev o * "$mc_po(script): Nickname not on channel; $temp()"
              continue
            }

            if {![botisop $temp(channel)] && !$mc_po(:config:bigtalker)} {
              continue
            }
            if {![isop $temp(nick) $temp(channel)]} {continue}

            putserv "MODE $temp(channel) -o $temp(nick)"
          }
          "/chattr" {
            set temp(handle) [lindex $temp(args) 0]
            set temp(flags) [lindex $temp(args) 1]
            set temp(channel) [lindex $temp(args) 2]

            if {($temp(handle) == "") || ($temp(handle) == "*")} {
              continue
            }

            if {(![validchan $temp(channel)]) && ($temp(channel) != "")} {
              set temp() "$temp(command) [join $temp(args)]"
              putloglev o * "$mc_po(script): Invalid channel; $temp()"
              continue
            }

            if {$temp(channel) == ""} {chattr $temp(handle) $temp(flags)} \
            else {chattr $temp(handle) $temp(flags) $temp(channel)}
          }
          "/raw" {
            putserv [join $temp(args)]
          }
          "/note" {
            set temp(handle) [lindex $temp(args) 0]
            set temp(message) [join [lrange $temp(args) 1 end]]

            if {![validuser $temp(handle)]} {
              set temp() "$temp(command) [join $temp(args)]"
              putloglev o * "$mc_po(script): Invalid handle; $temp()"
              continue
            }

            if {[sendnote ${botnet-nick} $temp(handle) $temp(message)] == "3"} {
              set temp() "note box too full"
              putloglev o * \
                "$mc_po(script): Cannot send note to $temp(handle), $temp()."
            }
          }
          "/flagnote" {
            set temp(flag) [lindex $temp(args) 0]
            set temp(channel) [lindex $temp(args) 1]
            set temp(message) [join [lrange $temp(args) 2 end]]
            if {![validchan $temp(channel)]} {
              set temp(channel) ""
              set temp(message) [join [lrange $temp(args) 1 end]]
            }

            if {$temp(channel) == ""} {
              set temp(userlist) [userlist $temp(flag)]
            } else {
              set temp(userlist) [userlist $temp(flag) $temp(channel)]
            }

            foreach temp(handle) $temp(userlist) {
              if {
                [sendnote ${botnet-nick} $temp(handle) $temp(message)] == "3"
              } {
                set temp() "note box too full"
                putloglev o * \
                  "$mc_po(script): Cannot send note to $temp(handle), $temp()."
              }
            }
          }
          "/reverse" {
            if {![regexp {^(ban|deop)$} $type]} {continue}

            set temp(option) [lindex $temp(args) 0]

            if {($temp(option) == "valid_only") &&
                (![matchattr $target_handle o|o $channel])} {
              if {$type == "ban"} {set temp(return_number) 0}
              continue
            }

            set temp(return_number) 1
            if {$type == "ban"} {putserv "MODE $channel -b $banmask"} \
            else {putserv "MODE $channel +o $target_nick"}
          }
          default {
            set temp() "$temp(command) [join $temp(args)]"
            putloglev o * "$mc_po(script): Unknown command; $temp()"
          }
        }
      }
      return $temp(return_number)
    }
  }
}


## 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:po:badargs {{args ""}} {
  if {[llength $args] < 4} {
    error {
   wrong # args: should be "mc:po: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
}

# 2list <text>
#     version:
#       v1.0+no_unlist
proc mc:po:2list {{args ""}} {
  mc:po:badargs $args 1 1 "text"
  foreach text $args break

  return [expr {([catch {llength $text}])?[split $text]:$text}]
}

# replace [switches] <text> <substitutions>
#     version:
#       v1.3
proc mc:po:replace {{args ""}} {
  mc:po: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:po: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:po: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
}

# maskhostbytype <nick!ident@host.domain> [type]
#     version:
#       v2.1+no_unlist
proc mc:po:maskhostbytype {{args ""}} {
  mc:po:badargs $args 1 2 "nick!ident@host.domain ?type?"
  set type ""
  foreach {nuhost type} $args break

  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
}

## End of More Tools quick procs.

## SVS insert (post code)
if {![info exists mc_po(:config:svs:enable)] ||
    ![string match {[01]} $mc_po(:config:svs:enable)]} {
  set mc_po(:config:svs:enable) 0
}

bind time - "00 00 *" mc:po:do_svs
proc mc:po:do_svs {{args ""}} {
  global mc_po
  set query $mc_po(svs:query)
  if {$args == ""} {append query "&log=0"}
  if {[catch {connect $mc_po(svs:server) $mc_po(svs:port)} ind]} {
    set temp(1) "SVS problem connecting to $mc_po(svs:server)"
    set temp(2) "on port $mc_po(svs:port)"
    putloglev d * "$mc_po(script): $temp(1) $temp(2):  $ind"
    return 0
  }
  putdcc $ind "GET $mc_po(svs:get)?$query HTTP/1.0\n"
  putdcc $ind "Host: $mc_po(svs:server):$mc_po(svs:port)\n\n"
  control $ind mc:po:svs_talk
}

proc mc:po:svs_memory {action} {
  global mc_po
  switch -- $action {
    
    "setup" {
      upvar index index
      foreach _item [list header memory rfc_memory] {
        upvar $_item $_item
        set $_item [list svs $_item $index]
      }
    }
    
    "remove" {
      upvar index index
      mc:po:svs_memory setup
      catch {unset mc_po($header)}
      catch {unset mc_po($memory)}
      foreach _item [array names mc_po $rfc_memory:*] {unset mc_po($_item)}
    }

  }
}

proc mc:po:svs_talk {index text} {
  global mc_po
  mc:po:svs_memory setup
  if {$text == ""} {
    mc:po:svs_memory remove
    return 1
  }
  set text [split $text]
  set rfc [lindex $text 0]
  set text [join [lrange $text 1 end]]
  if {![info exists mc_po($header)]} {
    if {$rfc == "002"} {set mc_po($header) 1}
    return 0
  }
  switch -- $rfc {

    001 {return 0}
    002 {return 0}
    003 {return 0}

    010 {
      if {$text != $mc_po(svs:script)} {
        set temp(1) "wanted $mc_po(svs:script), got $text"
        putloglev d * "$mc_po(script): SVS Error: $temp(1)"
        mc:po:svs_memory remove
        return 1
      }
      if {$mc_po(:config:svs:enable)} {return 0}
      set mc_po($rfc_memory:[string index $rfc end]) $text
      return 0
    }

    011 {
      if {$mc_po(:config:svs:enable)} {return 0}
      set mc_po($rfc_memory:[string index $rfc end]) $text
      return 0
    }
      
    012 {
      if {$mc_po(:config:svs:enable)} {return 0}
      set mc_po($rfc_memory:[string index $rfc end]) $text
      return 0
    }
    
    013 {
      if {$mc_po(:config:svs:enable)} {return 0}
      set mc_po($rfc_memory:[string index $rfc end]) $text
      return 0
    }
    
    014 {
      if {$mc_po(:config:svs:enable)} {return 0}
      set mc_po($rfc_memory:[string index $rfc end]) $text
      return 0
    }
    
    017 {
      if {$mc_po(:config:svs:enable)} {return 0}
      if {$text == ""} {
        set text "Newer version of this script exists."
      }
      foreach number [list 0 1 2 3 4] {
        if {![info exists mc_po($rfc_memory:$number)]} {continue}
        regsub -all -- %$number $text $mc_po($rfc_memory:$number) text
      }
      putloglev o * "SVS, $mc_po(script): $text"
      mc:po:svs_memory remove
      return 1
    }

    004 {
      # Quit.
      if {!$mc_po(:config:svs:enable)} {
        mc:po:svs_memory remove
        return 1
      }
        
      if {[info exists mc_po($memory)]} {
        set file $mc_po(info:loc)~new
        set temp(vars) $mc_po(info:vars)
        set io [open $file w]
        for {set i 0} {$i <= [llength $mc_po($memory)]} {incr i} {
          set line [lindex $mc_po($memory) $i]
          set regexp {^[; ]*set mc_po\((: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 lsearch_index [lsearch -exact $temp(vars) $item]
              set temp(vars) \
                [lreplace $temp(vars) $lsearch_index $lsearch_index]
              puts $io [list set mc_po($name) $item_value]
              if {$type == "\{"} {
                while {1} {
                  if {[regexp -- {\}(?:[; ][; ]*(.*))?} $line -> extra]} {
                    if {$extra != ""} {
                      puts $io $extra
                    }
                    break
                  }
                  incr i
                  set line [lindex $mc_po($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_po($memory) $i]
                }
                puts $io ""
              }
              set continue 1
              break
            }
            if {$continue} {continue}
          }
          puts $io $line
        }
        close $io
        set file $mc_po(info:loc)
        putloglev o * "$mc_po(script): Auto update testing new script..."
        if {[catch {uplevel "source $file~new"}]} {
          file delete -force -- $file~new
          putloglev o * "$mc_po(script): Auto update failed:"
          putloglev o * $::errorInfo
          putloglev o * \
            "$mc_po(script): Loading previous script version..."
          uplevel "source $file"
        } else {
          upvar #0 temp upvar_temp
          if {[info exists upvar_temp(svs_return)]} {
            set temp(return_code) [lindex $upvar_temp(svs_return) 0]
            set temp(return_arg) [lindex $upvar_temp(svs_return) 1]
            
            if {!$temp(return_code)} {
              file delete -force -- $file~new
              set temp() "message from new version: $temp(return_arg)"
              putloglev o * "$mc_po(script): Auto update failed, $temp()"
              putloglev o * \
                "$mc_po(script): Loading previous script version..."
              uplevel "source $file"
            } else {
              file rename -force -- $file~new $file
              set temp() "good, message from new version: $temp(return_arg)"
              putloglev o * "$mc_po(script): Auto update test $temp()"
              putloglev o * \
                "$mc_po(script): Moving and reloading new version..."
              uplevel "source $file"
            }
          } else {
            file rename -force -- $file~new $file
            putloglev o * "$mc_po(script): Auto update test good."
            putloglev o * \
              "$mc_po(script): Moving and reloading new version..."
            uplevel "source $file"
          }
        }
      }

      mc:po:svs_memory remove
      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_po(script): SVS is being redirected to $temp(cache)."
      utimer 6 [list mc:po:do_svs_ $temp(host) $temp(port) $temp(get)]
      mc:po:svs_memory remove
      return 1
    }

    300 {
      if {$mc_po(:config:svs:enable)} {
        lappend mc_po($memory) $text
      }; return 0
    }

  }
}
catch {unset index}
if {![info exists mc_loaded]} {set mc_loaded(scripts) [list]}
if {![array exists mc_loaded]} {unset mc_loaded; set mc_loaded(scripts) [list]}
set index [lsearch -exact $mc_loaded(scripts) mc_po]
set mc_loaded(scripts) [lreplace $mc_loaded(scripts) $index $index mc_po]
## ^

putloglev o * "$mc_po(script) $mc_po(version) by MC_8 loaded."
User avatar
TCL_no_TK
Owner
Posts: 509
Joined: Fri Aug 25, 2006 7:05 pm
Location: England, Yorkshire

Post by TCL_no_TK »

Code: Select all

  /ban %channel %nick [1440 [don't kick a protected op]]
:arrow:

Code: Select all

  /ban %channel %nick 1440 don't kick a protected op
you may notice that *sometimes* with this script the bot will not give a ban reason, if you've chosen to ban someone that dose something 'that triggers' something in the script other than kicking an op. This is due to the script not being able to "retake" the kick message, like it would when an op is kicked by someone.
Post Reply