####################################################
# by wiebe @ QuakeNet
#
# collect info from scripts loaded, and share over botnet
# allowing scripts to determine if other bots have the same script
# and adjust actions
#
####################################################


####################################################
# script:evnt
####################################################
bind evnt -|- loaded script:evnt
bind evnt -|- rehash script:evnt
bind evnt -|- prerehash script:evnt
proc script:evnt { t } {
  global scriptdb
  if {[string equal -nocase $t prerehash]} { unset scriptdb } else { putallbots "SCRIPT ?" }
}


####################################################
# script:link
####################################################
bind link -|- * script:link
proc script:link { b v } { putallbots "SCRIPT ?" }


####################################################
# script:bot
####################################################
bind bot -|- script script:bot
proc script:bot { b c t } {
  if {![string equal $c "SCRIPT"]} { return 0 }
  global scriptdb; set t [split $t]; set c [lindex $t 0]; set t [join [lrange $t 1 end]]
  set b [string tolower $b]; set t [string tolower $t]
  if {[string equal $c "?"]} {
    putbot $b "SCRIPT Y"
  } elseif {[string equal $c "Y"]} {
    if {[array size scriptdb] < 1} { return 0 }
    putbot $b "SCRIPT D"
    foreach e [lsort -dictionary [array names scriptdb]] {
      if {![string match "*,*" $e]} { putbot $b "SCRIPT A $e" }
    }
  } elseif {[string equal $c "D"]} {
    foreach e [lsort -dictionary [array names scriptdb]] {
      if {![string match "*,*" $e]} { continue }
      if {![string equal $b [lindex [split $e ,] 0]]} { continue }
      unset scriptdb($e)
    }
  } elseif {[string equal $c "A"]} { set scriptdb($b,$t) "1" }
}


####################################################
# script:disc
####################################################
bind disc -|- * script:disc
proc script:disc { b } {
  global scriptdb; set b [string tolower $b]
  foreach e [array names scriptdb] {
    if {![string match "*,*" $e]} { continue }
    if {![string equal $b [lindex [split $e ,] 0]]} { continue }
    unset scriptdb($e)
  }
}


####################################################
# script:check
####################################################
proc script:check { b s } {
  global scriptdb
  set b [string tolower $b]; set s [string tolower $s]
  return [info exists scriptdb($b,$s)]
}


####################################################
# script:help:msg
####################################################
bind msgm omn|omn "help script" script:help:msgm
proc script:help:msgm { n u h t } {
  if {[matchattr $h bkZ]} { return 0 }
  lappend o "script: usage script <name> \[<bot>\] (wildcards are allowed)"
  lappend o "script: shows info about the scripts that are loaded on this or a remote bot"
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "script: " } }
  putcmdlog "($n!$u) !$h! help script"
  return 1
}


####################################################
# script:msg
####################################################
bind msg omn|omn script script:msg
proc script:msg { n u h t } {
  if {[matchattr $h bkZ]} { return 0 }
  set o [script:script $h $t]
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "script: " } }
  return 1
}


####################################################
# script:dcc
####################################################
bind dcc -|- script script:dcc
proc script:dcc { h i t } {
  set o [script:script $h $t]
  foreach l $o { putidx $i $l }
  return 1
}


####################################################
# script:script
####################################################
proc script:script { h t } {
  global scriptdb; set t [split $t]; set b [lindex $t 1]; set t [lindex $t 0]
  regsub -all {[][\\]} $b {\\\0} c; regsub -all {[][\\]} $t {\\\0} u
  set c [string tolower $c]; set u [string tolower $u]
  set a 0; foreach d [bots] { if {[string match -nocase $c $d]} { incr a; set b $d } }
  if {[string equal $t ""]} {
    lappend o "script: usage script <name> \[<bot>\] (wildcards are allowed)"
    lappend o "script: shows info about the scripts that are loaded on this or a remote bot"
  } elseif {![string equal $b ""] && ![matchattr $h omn]} {
    lappend o "script: no access to view info from other bots"
  } elseif {![string equal $b ""] && [llength [bots]] < 1} {
    lappend o "script: no bots are linked"
  } elseif {![string equal $b ""] && $a < 1} {
    lappend o "script: no bot found matching $b"
    lappend o "script: currently linked bots: [join [lsort -dictionary [bots]] "  "]"
  } elseif {![string equal $b ""] && $a > 1} {
    lappend o "script: more than one bot found matching $b"
    lappend o "script: currently linked bots: [join [lsort -dictionary [bots]] "  "]"
  } elseif {![string equal $b ""]} {
    set r ""
    foreach e [lsort -dictionary [array names scriptdb]] {
      if {[string match "$c,$u" $e]} { lappend r [lindex [split $e ,] 1] }
    }
    if {[string equal $r ""]} {
      lappend o "script: no matching script found for '$t' on bot $b"
    } elseif {[string equal [llength $r] "1"]} {
      set $r [lindex $r 0]
      if {[info exists scriptdb($r)]} {
        lappend o "script: found 1 script matching '$t' on bot $b (showing local info)"
        foreach l $scriptdb($r) { lappend o "($r) $l" }
        lappend o "script: end of list for $r"
      } else {
        lappend o "script: found 1 script matching '$t' on bot $b (no local info available)"
      }
    } else {
      lappend o "script: found [llength $r] scripts matching '$t' on bot $b"
      lappend o "script: [join $r "   "]"
    }
  } else {
    set r ""
    foreach e [lsort -dictionary [array names scriptdb]] {
      if {[string match "*,*" $e]} { continue }
      if {[string match $u $e]} { lappend r $e }
    }
    if {[string equal $r ""]} {
      lappend o "script: no matching script found for '$t'"
    } elseif {[string equal [llength $r] "1"]} {
      lappend o "script: found 1 script matching '$t'"
      set $r [lindex $r 0]
      foreach l $scriptdb($r) { lappend o "($r) $l" }
      lappend o "script: end of list for $r"
    } else {
      lappend o "script: found [llength $r] scripts matching '$t'"
      lappend o "script: [join $r "   "]"
    }
  }
  return $o
}


set scriptdb(script) {
  "provides script command and collects info from other scripts, shares this info over the botnet. other scripts can request this info. this allows a script to determine if another bot has the same script loaded and adjust its course of action based on that"
  "think about a script that sends a warning or a kick, if two or more bots on the channel have the same script and perform the same re-action, a user would get 2 or more warnings/kicks etc, this would be messy."
}

