####################################################
# by wiebe @ QuakeNet
#
#	ban is set:
#	 [11:10] @bot sets mode: +b *!*@host.com
#	netsplit:
#	 [11:18] Quits: +nick (user@host) (*.net *.split)
#	ban is removed:
#	 [11:20] @bot sets mode: -b *!*@host.com
#	netmerge:
#	 [11:24] Joins: nick (user@host)
#	 [11:24] irc.server.org sets mode: +vb nick *!*@host.com
#
#	even though the ban *!*@host.com expired, due to the netsplit, it is set again
#	this script saves removed bans for a while and bounces those bans set by servers
####################################################

####################################################
# netsplitbans:mode
####################################################
bind mode -|- "% ?b" netsplitbans:mode
bind mode -|- "% +h" netsplitbans:mode
bind mode -|- "% +o" netsplitbans:mode
proc netsplitbans:mode { n u h c m t } {
  if {![validchan $c]} { return 1 }
  global netsplitbans bounce-bans bounce-modes
  set x [clock seconds]
  if {[string equal $m "-b"]} {
    set netsplitbans($c,$t) $x
  } elseif {[string equal $m "+b"]} {
    if {![string equal $n ""]} { return 0 }
    if {[string match "*@*" $u]} { return 0 }
    if {![string equal $h "*"]} { return 0 }
    if {[info exists bounce-bans] && [string equal ${bounce-bans} "1"]} { return 0 }
    if {[info exists bounce-modes] && [string equal ${bounce-modes} "1"]} { return 0 }
    if {[isban $t $c]} { return 1 }
    if {![info exists netsplitbans($c,$t)]} { return 0 }
    if {![string is digit $netsplitbans($c,$t)]} { return 0 }
    if {[expr $x - $netsplitbans($c,$t)] > "3600"} { return 0 }
    if {![botisop $c] && ![botishalfop $c]} { return 0 }
# ircu 2.10.12 netmerge modes come from local server
# /opmode etc comes from HIS servername (depends on settings.., we'll see)
    if {[string equal $u "*.quakenet.org"]} { return 0 }
    if {[string equal $u "*.undernet.org"]} { return 0 }
    pushmode $c -b $t
    putloglev k $c "$c: bouncing expired ban $t"
    if {![string equal [info procs ircconsole] ""]} {
      ircconsole $c n NETSPLIT "bouncing expired ban $t"
    }
  } elseif {[string match {+[ho]} $m] && [isbotnick $t]} {
    set s ""
    foreach b [chanbans $c] {
      set t [lindex $b 0]
      if {![info exists netsplitbans($c,$t)]} { continue }
      if {[isban $t $c]} { continue }
      pushmode $c -b $t
      putloglev k $c "$c: bouncing expired ban $target"
      lappend s $t
    }
    set s [join $s]
    if {![string equal $s ""]} {
      if {![string equal [info procs ircconsole] ""]} {
        ircconsole $c n NETSPLIT "bouncing expired bans: $s"
      }
    }
  }
}


####################################################
# netsplitbans:time
#
# check saves bans and remove expired ones
####################################################
bind time -|- "?2 * * * *" netsplitbans:time
proc netsplitbans:time { mi ho da mo ye } {
  global netsplitbans; set m [clock seconds]
  foreach n [array names netsplitbans] {
    set c [lindex [split $n ,] 0]; set b [join [lrange [split $n ,] 1 end] ,]
    if {![validchan $c] || [expr $m - $netsplitbans($n)] > "3600"} { unset netsplitbans($n) }
  }
}


set scriptdb(netsplitbans) {
  "keeps track of channel bans that are removed and removes them again should they get set again as a result of a netsplit and netmerge."
}

