#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



#log stuff? 1=yes, 0=no
set paranoid(log) 1


#create +noparanoid channel setting
setudef flag noparanoid



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



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



#log text
proc paranoid:log { text } {
  global paranoid
    if { ![info exists paranoid(log)] || ![string equal $paranoid(log) 1] || [string equal $text ""] } { return 0 }
  putlog "Paranoid: $text"
}



#rehash or (re)start
if { [string equal $server ""] } {
  paranoid:log "changing to random nick"
  set paranoid(nick) $nick
  set nick [paranoid:randnick]
}



#connect / disconnect event
bind evnt -|- "init-server" paranoid:evnt
bind evnt -|- "disconnect-server" paranoid:evnt
proc paranoid:evnt { type } {
  global paranoid
  if { [string equal -nocase $type "init-server"] } {
    paranoid:log "deactivating channels"
    foreach chan [channels] {
      if { ![channel get $chan noparanoid] && ![channel get $chan inactive] } {
        channel set $chan +inactive
      }
    }
    set paranoid(do) "1"
  } elseif { [string equal -nocase $type disconnect-server] } {
    paranoid:log "changing to random nick"
    set paranoid(nick) $::nick
    set ::nick [paranoid:randnick]
  }
}



#catch host changes and S-line
bind raw -|- "396" paranoid:hosthidden
bind raw -|- "399" paranoid:hosthidden

proc paranoid:hosthidden { server numeric text } {
  global paranoid

  if { ![info exists paranoid(do)] || ![string equal $paranoid(do) 1] } { return 0 }
  set target [lindex [split $text] 0]

#using S-line
  if { [string equal $numeric 399] } {
    set text [string range [join [lrange [split $text] 1 end]] 1 end]
    if { ![string equal -nocase $text "Using S-line privilege"] } { return 0 }
    paranoid:log "$text"

#hidden host (usermode +x / +h)
  } elseif { [string equal $numeric 396] } {
    set host [lindex [split $text] 1]
    set text [string range [join [lrange [split $text] 2 end]] 1 end]
    if { ![string equal -nocase $text "is now your hidden host"] } { return 0 }
    paranoid:log "$host $text"
  }
  paranoid:log "changing nick back to $paranoid(nick)"
  set ::nick $paranoid(nick)
  set paranoid(do) 2
}



#nick change
bind nick -|- * paranoid:nick

proc paranoid:nick { nick host handle chan newnick } {
  global paranoid server
  if { [string equal $server ""] } { return 0 }
  if { ![isbotnick $nick] } { return 0 }
  if { ![info exists paranoid(do)] } { return 0 }
  if { ![string equal $paranoid(do) 2] } { return 0 }
  paranoid:join
  set paranoid(do) 0
}



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

