####################################################
# by wiebe @ QuakeNet
#
####################################################


####################################################
# hiddenbans:join
####################################################
bind join -|- * hiddenbans:join; bind rejn -|- * hiddenbans:join 
proc hiddenbans:join { n u h c } { hiddenbans:checkuser $c $n $u $h }


####################################################
# hiddenbans:nick
####################################################
bind nick -|- * hiddenbans:nick
proc hiddenbans:nick { n u h c m } { hiddenbans:checkuser $c $m $u $h }


####################################################
# hiddenbans:endofwho
####################################################
bind raw -|- 315 hiddenbans:endofwho
proc hiddenbans:endofwho { s n t } {
  if {$n != 315} { return 0 }
  set t [split $t]; set c [lindex $t 1]
  if {![validchan $c] || ![botonchan $c] || [channel get $c inactive]} { return 0 }
  if {[expr [getchanjoin $::botnick $c] + 180] < [clock seconds]} { return 0 }
  if {[llength [chanlist $c]] <= 1} { return 0 }
  hiddenbans:checkall $c
  return 0
}


####################################################
# hiddenbans:checkall c = valid chan
####################################################
proc hiddenbans:checkall { c } {
  foreach n [chanlist $c] {
    if {[isbotnick $n]} { continue }
    set h [nick2hand $n $c]
    if {[matchattr $h bfvlomn|fvlomn $c] && ![matchattr $h Z]} { continue }
    if {[matchattr $h k|k $c]} { continue }
    set u [getchanhost $n $c]
    if {[matchban $n!$u $c] || ![matchban @$n!$u $c]} { continue }
    hiddenbans:ban $c $n $u
  }
}


####################################################
# hiddenbans:checkuser c = chan, n = nick, u = user@host, h = handle
####################################################
proc hiddenbans:checkuser { c n u h } {
  if {![validchan $c] || ![botonchan $c] || [channel get $c inactive] || [isbotnick $n]} { return 0 }
  if {[matchattr $h bfvlomn|fvlomn $c] && ![matchattr $h Z]} { return 0 }
  if {[matchattr $h k|k $c]} { return 0 }
  if {[matchban $n!$u $c] || ![matchban @$n!$u $c]} { return 0 }
  hiddenbans:ban $c $n $u
}


####################################################
# hiddenbans:checkmask m = mask, c = chan
####################################################
proc hiddenbans:checkmask { m {c ""} } {
  if {![string match @*!*@* $m]} { return 0 }
  if {$m == "@*!*@*"} { return 0 }
  if {$c == ""} { set d [channels] } elseif {[validchan $c]} { lappend d $c }
  foreach c $d {
    if {![botonchan $c] || [channel get $c inactive]} { continue }
    set hit 0; set max 15
    foreach n [chanlist $c] {
      if {$hit >= $max} { break }
      if {[isbotnick $n]} { continue }
      set h [nick2hand $n $c]
      if {[matchattr $h bfvlomn|fvlomn $c] && ![matchattr $h Z]} { continue }
      if {[matchattr $h k|k $c]} { continue }
      set u [getchanhost $n $c]
      if {[matchban $n!$u $c]} { continue }
      regsub -all {[][\\]} $m {\\\0} m
      if {![string match -nocase $m @$n!$u]} { continue }
      hiddenbans:ban $c $n $u
      incr hit
    }
  }
  return 0
}


####################################################
# hiddenbans:ban c = valid chan, n = nick, u = user@host
####################################################
proc hiddenbans:ban { c n u } {
  set i [hiddenbans:getinfo $c $n $u]
  set g [lindex $i 0]; set r [lindex $i 1]; set b [lindex $i 2]; set l 240
  if {$g == 0} { return 0 }
  set m *!*@[lindex [split $u @] 1]
  if {$g == 2} {
    if {[info procs newban:ban] != ""} { newban:ban $m $b $r $l } else { newchanban $c $m $b $r $l }
  } elseif {$g == 1} {
    if {[info procs newchanban:ban] != ""} { newchanban:ban $c $m $b $r $l } else { newchanban $c $m $b $r $l }
  }
}


####################################################
# hiddenbans:getinfo c = valid chan, n = nick, u = user@host
# '0/1/2 reason by', 0 = none, 1 = chan, 2 = global
####################################################
proc hiddenbans:getinfo { c n u } {
  if {[matchban @$n!$u]} {
    foreach e [banlist] {
      regsub -all {[][\\]} [lindex $e 0] {\\\0} b
      if {![string match -nocase $b @$n!$u]} { continue }
      return [list 2 [lindex $e 1] [lindex $e 5]]
    }
  }
  if {![validchan $c] || ![matchban @$n!$u $c] || [isop $n $c] || [ishalfop $n $c] || [isvoice $n $c]} { return 0 }
  foreach e [banlist $c] {
    regsub -all {[][\\]} [lindex $e 0] {\\\0} b
    if {![string match -nocase $b @$n!$u]} { continue }
    return [list 1 [lindex $e 1] [lindex $e 5]]
  }
  return 0
}


set ::scriptdb(hiddenbans) {
  "provides hidden bans support, prefix bans with @ to make them hidden, any matching targets will be banned on *!*@host"
}

