#by wiebe @ QuakeNet



#help op pub
bind pubm omn|omn "% ${botnet-nick} help op" c_op:help:pub

proc c_op:help:pub { nick uhost handle chan text } {
  lappend output "Usage: op \[<nick1> <nick2> .. <nickN>\]"
  lappend output "Ops you on the channel. Flag +m or +n is needed to op other users."
  if { [catch {set x [cnotice $nick $output]} error] || !$x } {
    foreach t $output { puthelp "NOTICE $nick :$t" }
  }
  putloglev c $chan "[lindex [split $text] 1]: $nick $uhost $handle $chan [join [lrange [split $text] 2 end]]"
}



#help op msg
bind msgm omn|omn "help op" c_op:help:msg

proc c_op:help:msg { nick uhost handle text } {
  lappend output "Usage: op <channel> \[<nick1> <nick2> .. <nickN>\]"
  lappend output "Ops you on the channel. Flag +m or +n is needed to op other users."
  lappend output "Usage: op \[<channel1> <channel2> .. <channelN>\]"
  lappend output "Ops you on all or the given channels."
  if { [catch {set x [cnotice $nick $output]} error] || !$x } {
    foreach t $output { puthelp "NOTICE $nick :$t" }
  }
  putcmdlog "($nick!$uhost) !$handle! $text"
}



#op self
bind pubm omn|omn "% ${botnet-nick} op" c_op:pub:self

proc c_op:pub:self { nick uhost handle chan text } {
  if { ![botisop $chan] } {
    lappend output "I am not a channel operator on $chan"
  } elseif { [matchattr $handle d|d $chan] } {
    lappend output "You can not gain op with deny-op flag (+d) on $chan"
  } elseif { [isop $nick $chan] } {
    lappend output "You appear to be opped already on $chan"
  } else {
    lappend output "Opped you on $chan"
    pushmode $chan +o $nick
  }
  if { [catch {set x [cnotice $nick $output]} error] || !$x } {
    foreach t $output { puthelp "NOTICE $nick :$t" }
  }
  putloglev c $chan "[lindex [split $text] 1]: $nick $uhost $handle $chan [join [lrange [split $text] 2 end]]"
}



#op other
bind pubm omn|omn "% ${botnet-nick} op *" c_op:pub:opother

proc c_op:pub:opother { nick uhost handle chan text } {
  set targets [lrange [split $text] 2 end]
  if { ![botisop $chan] } {
    lappend output "I am not a channel operator on $chan"
  } elseif { [matchattr $handle o|o $chan] && ![matchattr $handle mn|mn $chan] } {
    lappend output "No access to op others on $chan (need +m or +n flag)."
  } elseif { [string equal $targets ""] } {
    lappend output "Usage: op \[<nick1> <nick2> .. <nickN>\]"
  } else {
    set output [c_op:op:others $chan $targets]
  }
  if { [catch {set x [cnotice $nick $output]} error] || !$x } {
    foreach t $output { puthelp "NOTICE $nick :$t" }
  }
  putloglev c $chan "[lindex [split $text] 1]: $nick $uhost $handle $chan [join [lrange [split $text] 2 end]]"
}



#op msg
bind msg omn|omn op c_op:msg

proc c_op:msg { nick uhost handle text } {
  set chan [lindex [split $text] 0]
  set targets [lrange [split $text] 1 end]

#nothing giving, or invalid chan, or no access, other check
  if { [string equal $text ""] || ![validchan $chan] || ![matchattr $handle mn|mn $chan] || [c_op:nickorchan "$text"] } {
    if { [string equal $text ""] } { set text [channels] }
    set output [c_op:op:self $nick $handle "$text"]
  } elseif { ![botisop $chan] } {
     lappend output "$chan\017 I am not a channel operator there."
  } elseif { ![string equal $targets ""] && [matchattr $handle mn|mn $chan] } {
    set output [c_op:op:others $chan $targets]
  }
  if { [catch {set x [cnotice $nick $output]} error] || !$x } {
    foreach t $output { puthelp "NOTICE $nick :$t" }
  }
  return 1
}



#op user one all or given channels
proc c_op:op:self { nick handle channels } {
  set opchan ""
  foreach chan [split $channels] {
    if { [validchan $chan] && [botisop $chan] && ![isop $nick $chan] && [matchattr $handle omn|omn $chan] && ![matchattr $handle d|d $chan] } {
      lappend opchan $chan
      pushmode $chan +o $nick
    }
  }
  if { [string equal $opchan ""] } {
    lappend output "Found no channels to op you on."
  } else {
    lappend output "Opped you on: [join $opchan]"
  }
  return $output
}



#op targets
proc c_op:op:others { chan targets } {
  set bitch 0
  set invalid 0
  foreach t [split $targets] {
    if { [onchan $t $chan] && ![isop $t $chan] && ![matchattr [nick2hand $t] d|d $chan] } {
      if { ![channel get $chan bitch] || [matchattr [nick2hand $t] omn|omn $chan] } {
        pushmode $chan +o $t
      } else { set bitch 1 }
    } else { set invalid 1 }
  }
  if { $bitch } { lappend output "Some targets were not opped because +bitch prevents that." }
  if { $invalid } { lappend output "Some targets were invalid, not on the channel, already opped, or had deny-op flag (+d)." }
  lappend output "Opped other users on $chan"
  return $output
}



#returns if "chan1 chan2 chanN" is used or "chan nick1 nick2 nickN", returns 1 for chans
proc c_op:nickorchan { targets } {
  if { [string equal $targets ""] } { return 1 }
  if { [string equal [llength $targets] 1] } { return 1 }
  set chanc 0; set nickc 0
  set chan [lindex [split $targets] 0]
  set targets [join [lrange [split $targets] 1 end]]
  foreach t [split $targets] {
    if { [validchan $t] || ![onchan $t $chan] || [isop $t $chan] || [string match {[#&]*} $t] } {
      incr chanc 1
    } elseif { [onchan $t $chan] } { incr nickc 1 }
  }
  if { $chanc >= $nickc } { return 1 } else { return 0 }
}

