####################################################
# by wiebe @ QuakeNet
#
# set +noparanoid on a channel when:
#  1) you want it to join straight away and not wait for spoofed host
#  2) if you want the channel to stay +inactive
#
####################################################

setudef flag noparanoid

####################################################
# to prevent an ugly random botnet-nick, set it here if it is not set
####################################################
if {[info exist {::botnet-nick}] && ${::botnet-nick} == ""} { set ::botnet-nick $::nick; set ::keep-nick 1 }


####################################################
# paranoid:randnick
####################################################
proc paranoid:randnick { } {
  global nick-len
  if {![info exists nick-len]} { set l 9 } else { set l ${nick-len} }
  set n "abcdefghijklmnopqrstuvwxyz"
  set n "[string index $n [rand 26]]"
  set n "$n[md5 [rand 999999999]]"
  set n "[string range $n 0 [expr $l -1]]"
  return $n
}


####################################################
# rehash or (re)start
####################################################
if {$::server == ""} {
  set paranoid(nick) $::nick; set ::nick [paranoid:randnick]
  putloglev s * "paranoid: changing to random nick $::nick"
}

if {[info exists ::paranoid(do)]} {
  if {$::paranoid(do) == 1} { bind raw -|- "396" paranoid:raw; bind raw -|- "399" paranoid:raw }
  if {$::paranoid(do) == 2} { bind nick -|- * paranoid:nick }
}


####################################################
# paranoid:evnt
####################################################
bind evnt -|- "init-server" paranoid:evnt; bind evnt -|- "disconnect-server" paranoid:evnt
proc paranoid:evnt { t } {
  global paranoid nick
  set t [string tolower $t]
  if {$t == "init-server"} {
    putloglev s * "paranoid: deactivating channels"
    foreach c [channels] { if {![channel get $c noparanoid] && ![channel get $c inactive]} { channel set $c +inactive } }
    set paranoid(do) 1
    bind nick -|- * paranoid:nick; bind raw -|- "396" paranoid:raw; bind raw -|- "399" paranoid:raw
  } elseif {$t == "disconnect-server"} {
    set paranoid(nick) $nick; set nick [paranoid:randnick]
    putloglev s * "paranoid: changing to random nick $nick"
  }
}


####################################################
# paranoid:raw
####################################################
proc paranoid:raw { s n t } {
  global paranoid nick
  if {![info exists paranoid(do)]} { return 0 }
  if {$paranoid(do) != 1} { return 0 }
  set d [lindex [split $t] 0]
# using S-line
  if {$n == 399} {
    set t [string range [join [lrange [split $t] 1 end]] 1 end]
    if {![string equal -nocase $t "Using S-line privilege"]} { return 0 }
    putloglev s * "paranoid: $t"
# hidden host (usermode +x / +h / -h)
  } elseif {$n == 396} {
    set h [lindex [split $t] 1]
    set t [string range [join [lrange [split $t] 2 end]] 1 end]
    if {![string equal -nocase $t "is now your hidden host"]} { return 0 }
    putloglev s * "paranoid: $h is now my hidden host"
  }
  set n $paranoid(nick); set nick $n; set paranoid(do) 2
  putloglev s * "paranoid: changing nick back to $n"
  bind nick -|- * paranoid:nick
  catch {unbind raw -|- "396" paranoid:raw}
  catch {unbind raw -|- "399" paranoid:raw}
  return 0
}


####################################################
# paranoid:nick
####################################################
proc paranoid:nick { n u h c m } {
  global paranoid server
  if {$server == ""} { return 0 }
# some thing is borked with eggdrop here..
# on connect isbotnick returns 1 for nick, else it returns 1 for newnick!?
  if {![isbotnick $n] && ![isbotnick $m]} { return 0 }
  if {![info exists paranoid(do)]} { return 0 }
  if {$paranoid(do) != 2} { return 0 }
  paranoid:join; set paranoid(do) 0
  catch {unbind nick -|- * paranoid:nick}
  catch {unbind raw -|- "396" paranoid:raw}
  catch {unbind raw -|- "399" paranoid:raw}
  return 0
}


####################################################
# paranoid:join
####################################################
proc paranoid:join { } {
  global paranoid
  putloglev s * "paranoid: activating channels"
  foreach c [channels] { if {![channel get $c noparanoid] && [channel get $c inactive]} { channel set $c -inactive } }
}


set scriptdb(paranoid) {
  "keeps the bot out of sight until it has a hidden host (+x / +h), set +inactive +noparanoid to make and keep a channel inactive. set -inactive +noparanoid to make the bot join the channel as it would normally. set -inactive -noparanoid to let the bot only join this channel after getting a hidden host."
}

