#################################################################
#             «»«»«»«»«»«»«»«»«»«»«»«»            #
#             «»   X-TreMe.TCL 1.5 By BoMeR   «»            #
#               «»   Your Cmd Char is '!'   «»              #
#                 «»   Channel Commands   «»                #
#                    «»    «» «»     «»                   #
#################################################################

##################################################################
#                                                                #
#   might not want these...                                      #
#   they aren't password protected and give people a             #
#   chance to get ops if they have the same hostmask as a user   #
#   with this access                                             #
#                                                                #
##################################################################

bind pub o !up pub_do_up
bind pub o !op pub_do_op
bind pub o !deop pub_do_deop

### You may not want these either...they 
### are public mass mode changes....
### like mass op and mass deop and mass kick

bind pub m !mop pub_mass_op
bind pub m !mdeop pub_mass_deop
bind pub m !mkick pub_mass_kick

####################### PUBLIC COMMANDS #########################

bind pub - !date pub_do_dat
bind pub m !link pub_do_link
bind pub f !sendnote pub_do_note
bind pub - !version pub_say_ver
bind pub m !cycle pub_cycle
bind pub - !time pub_do_tim
bind pub m !flags pub_do_chattr
bind pub o !whois pub_whos
bind pub f !server pub_do_srv
bind pub o !status pub_do_status
bind pub o !chaninf pub_chan_inf
bind pub m !setmode pub_do_ccs
bind pub p !chat pub_chat
bind pub o !invite pub_invite
bind pub f !channels pub_do_chans
bind pub o !setcom pub_do_setcom
bind pub o !setinfo pub_do_sinfo
bind pub o !mode pub_do_mode
bind pub o !help pub_do_help
bind pub m !adduser pub_add_user
bind pub o !msg pub_do_msg
bind pub f !topic pub_do_topic
bind pub f !say pub_do_say
bind pub o !bk pub_do_ban
bind pub f !ping pub_do_ping
bind pub o !channel pub_show_channel
bind pub m !save pub_do_save
bind pub m !del pub_do_del
bind pub o !k pub_do_kick
bind pub m !shit pub_do_pban
bind pub f !away pub_do_away
bind pub m !cnick pub_do_nick
bind pub n !jump pub_do_jump 

################## MSG Commands ######################

bind msg p chat msg_chat
bind msg m join msg_botjoin
bind msg m leave msg_botleave
bind msg o channels msg_channels
bind msg o cycle msg_cycle

################# DCC Commands #######################

bind dcc p xthelp dcc_xthelp
bind dcc p pubhelp dcc_xtpubhelp
bind dcc o cycle dcc_botcycle
bind dcc m join dcc_botjoin
bind dcc m leave dcc_botleave
bind dcc n topic dcc_settopic
bind dcc o enforcemode dcc_do_mode
bind dcc o mode dcc_do_mode2
bind dcc m setmode dcc_chchanmodes
bind dcc o channels dcc_channels
bind dcc m massop mass_op
bind dcc m pinvite do_pinvite
bind dcc m massdeop mass_deop
bind dcc m masskick mass_kick
bind dcc m resynch resynch_deop
bind dcc p msghelp dcc_xtmsghelp
bind dcc m flagnote flag_note

set flag5 i

####################### Join Part Commands #####################
                                                               #
bind join i * auto_op
bind sign - * set_part_reason
bind part - * just_left
                                                               #
#######################    CTCP COMMANDS    ####################

#bind ctcp - "ECHO*" anti_echo

#################  AWAY MESSAGES ###############################
#                                                              #
#    Change these to Suit what you want.                       #
#                                                              #
set awaymsgs {
  {I am away)}
  {Away}
  {I am away....( Dont Bug Me Please!! )}
  {Guess what!...  im away..}
  {Im gonna be away a while!}
  {Why am i away?? }
  {lalala   im away!   lalalala }
}
#                                                               #
#################################################################

set defchanoptions {chanmode "+snt-pm" idle-kick 0}
set defchanmodes {-clearbans +enforcebans +dynamicbans +userbans -autoop -bitch +greet +protectops +statuslog +stopnethack -revenge}
set chanfile "chanfile"
set topicfile "topics"



    
proc auto_op {nick uhost hand chan} {
  putserv "MODE $chan +o $nick"
}

###############################################################
##                                                           ##
## «» You shouldnt Need to changel Anything Below Here «»  ##
##                                                           ##
###############################################################

proc pub_chat {nick host handle channel arg} {
  global telnet
  if {$telnet == 0} {
    putserv "PRIVMSG $nick :Sorry,  Your Host is not Reachable at this time. please try again later. =( "
    return 0
  }
  putserv "PRIVMSG $nick :\001DCC CHAT chat [myip] $telnet\001"
  return 1
}

proc dcc_xthelp {hand idx arg} {
putdcc $idx " "
putdcc $idx "### X-TreMe Help Requested by $hand ###"
putdcc $idx " "
putdcc $idx "### DCC Help (Commands in DCC Chat)"
putdcc $idx " "
putdcc $idx "Commands     Flags Required     Description"
putdcc $idx " "
putdcc $idx " .xthelp              -  +p  - Give you this Msg"
putdcc $idx " .pubhelp             -  +p  - Public Commands Help"
putdcc $idx " .msghelp             -  +p  - Msg Commands Help"
putdcc $idx " .msghelp             -  +p  - Msg Commands Help"
putdcc $idx " .massop <channel>    -  +m  - Ops all Masters and ops or specified hostmask"
putdcc $idx " .massdeop <channel>  -  +m  - De Ops all But Masters or Deops specified hostmask"
putdcc $idx " .massdeop <channel>  -  +m  - Kicks all But Masters and Ops or Kicks specified hostmask"
putdcc $idx " .cycle <channel>     -  +o  - Makes me Cycle a channel (Leave and Join)"
putdcc $idx " .resynch <channel>   -  +o  - Makes me Kick all users out and Cycle a channel to resynch it."
putdcc $idx " .join <channel>      -  +m  - Makes me join a channel."
putdcc $idx " .leave <channel>     -  +m  - Makes me leave a channel."
putdcc $idx " .topic <console #>   -  +m  - changes the Console Channels Topic."
putdcc $idx " .setmode <console #> -  +m  - changes the Console Channels Modes. (+bitch autoop etc)"
putdcc $idx " .mode <console #>    -  +m  - changes the Console Channels Modes. (+stn-pmi  etc)"
putdcc $idx " .Flagnote            -  +m  - Sends a note to everyone with the specified flag."
putdcc $idx " .enforcemode         -  +m  - changes the Console Channels Modes. (+stn-pmi  etc) (Cont'd)"
putdcc $idx " .enforcemode (Cont'd)- <console #> <modes>(note you must use the whole modes to enforce) ie. '.enforcemode +stn-pmik'"
putdcc $idx " "
putdcc $idx "### End of DCC Commands"

  return 1
}

proc dcc_xtpubhelp {hand idx arg} {
putdcc $idx "### X-TreMe Help Requested by $hand ###"
putdcc $idx " "
putdcc $idx "### Public Commands (Preformed in Channel)"
putdcc $idx "### All Public commands Preceded With your Cmd Char" 
putdcc $idx " "
putdcc $idx "Commands     Flags Required     Description"
putdcc $idx " " 
putdcc $idx "date                -  +f  - Tells Date"
putdcc $idx "link <bot>          -  +m  - links Remote bot"
putdcc $idx "sendnote            -  +f  - Sends a note"
putdcc $idx "version             -  +f  - Tells Version"
putdcc $idx "cycle               -  +o  - Makes me Cycle the chan"
putdcc $idx "time                -  +f  - Tells Time"
putdcc $idx "whois <nick>        -  +f  - Tells about nick"
putdcc $idx "server              -  +f  - Tells server im on"
putdcc $idx "status              -  +m  - Status Report"
putdcc $idx "setmode <#> <Modes> -  +m  - Changes modes (+-autoop etc)"
putdcc $idx "chat                -  +p  - Makes me DCC chat with you."
putdcc $idx "channels            -  +f  - Tells channels i am on."
putdcc $idx "channel <channel>            -  +f  - Lists channel onfo for a channel."
putdcc $idx "flags <nick>        -  +m  - Makes me Change a users Flags."
putdcc $idx "up                  -  +o  - Makes me Op you."
putdcc $idx "op <nick >          -  +o  - Makes me Op someone else."
putdcc $idx "mop                 -  +m  - Makes me op all masters and Ops, or a specified hostmast."
putdcc $idx "mdeop               -  +m  - Makes me De op all but my masters, or a specified hostmast."
putdcc $idx "mkick               -  +m  - Makes me kick all but my masters, or a specified hostmast."
putdcc $idx "mode <modes>        -  +o  - Changes chanmodes (+il etc.)"
putdcc $idx "help                -  +o  - More Help"
putdcc $idx "adduser <nick>      -  +m  - Adds a User"
putdcc $idx "msg <nick> <message>-  +f  - Makes me Msg someone"
putdcc $idx "topic <topic>       -  +f  - Changes Channel Topic"
putdcc $idx "say <phrase>        -  +f  - Makes me Talk"
putdcc $idx "bk <nick>           -  +o  - Bans Kicks Nick (Temp)"
putdcc $idx "ping                -  +f  - Check my Lag"
putdcc $idx "deop <nick>         -  +o  - Makes me Deop a User"
putdcc $idx "k <nick>            -  +o  - Makes me Kick a User"
putdcc $idx "shit <nick>         -  +m  - Makes me Permban Someone"
putdcc $idx "away <away message> -  +f  - Marks me as Away"
putdcc $idx " "
putdcc $idx "### End of Public Commands"

  return 1
}

proc dcc_xtmsghelp {hand idx arg} {
global botnick
putdcc $idx " "
putdcc $idx "### X-TreMe Help Requested by $hand ###"
putdcc $idx " "
putdcc $idx "###  Msg Help (Commands preformed through Private Messages)"
putdcc $idx " "
putdcc $idx "    All Comands Preceded With \002 /msg $botnick \002"
putdcc $idx " "
putdcc $idx "Commands     Flags Required     Description"
putdcc $idx " "
putdcc $idx " Chat              -  +p  - Bot Will Start a DCC Chat with you. (In case you cant initiate one)"
putdcc $idx " Channels          -  +o  - Tells all Channels i am on"
putdcc $idx " Join <chan>  <PW> -  +m  - Adds a channel for me to monitor."
putdcc $idx " Leave <chan> <Pw> -  +m  - Makes me no longer monitor that channel."
putdcc $idx " Cycle <Chan> <PW> -  +o  - Makes me Join and Part a channel."
putdcc $idx " "
putdcc $idx "### End of Msg Commands"
 
     return 1
}

proc pub_do_say {nick host handle channel arg} {
set who [lindex $arg 0] 
set why [lrange $arg 1 end] 
if {$who == ""} {
putserv "NOTICE $nick :Usage: SAY <What you want me to say to the channel.>"
return 1
}
putserv "PRIVMSG $channel :$who $why"
return 1
} 

proc pub_invite {nick host handle channel arg} {

global botnick

set who [lindex $arg 0]
set why [lrange $arg 1 end]
if {$who == ""} {
putserv "NOTICE $nick :Usage: Invite <nick> <channel>"
return 1
}
if {$why == ""} {
if {[lsearch [string tolower [channels]] [string tolower $who]] >= 0} {
if {[onchan $nick $who]} {
          putserv "NOTICE $nick : «»  $nick   is already on $channel. «»  "
          return 0
          }
          if {![isop $botnick $who]} {
          putserv "NOTICE $nick : «» X-TreMe Status:  I cant help you right now because im not a channel op! «» "
          return 1
          }
       putserv "INVITE $nick $who"
       putserv "NOTICE $nick : «» I Invited $nick to $who «» "
       return 0
       }
     if {![isop $botnick $channel]} {
     putserv "NOTICE $nick : «» X-TreMe Status:  I cant help you right now because im not a channel op! «» "
     return 1
    }
    if {[onchan $who $channel]} {
          putserv "NOTICE $nick : «»  $who   is already on $channel. «»  "
          return 0
          }
putserv "INVITE $who $channel"
putserv "PRIVMSG $channel : «»  $who  has Been Invited to This channel Requested by $nick «» "
return 1
}
if {[lsearch [string tolower [channels]] [string tolower $why]] <= -1} {
putserv "NOTICE $nick : «» X-TreMe Status:  I Dont Enforce Channel $why «» "
return 0
}
if {![onchan $botnick $why]} {
putserv "NOTICE $nick : «» X-TreMe Status:  I am not currently on $why «» "
return 1
}
if {![isop $botnick $why]} {
putserv "NOTICE $nick : «» X-TreMe Status:  I cant help you right now because im not a channel op! «» "
return 1
}
if {[onchan $who $why]} {
          putserv "NOTICE $nick : «»  $who   is already on $channel. «»  "
          return 0
          }
putserv "INVITE $who $why"
putserv "PRIVMSG $why : «»  $who  has Been Invited to This channel Requested by $nick «» "
}

proc pub_whos {nick uhost handle channel testes} {
  global botnick
  set ctr 0
  set arg [lindex $testes 0]
  for {set channelinfo 0} {$channelinfo < [llength [channels]]} {incr channelinfo} {
  set channel2 [lindex [channels] $channelinfo]
   if {[validuser $arg]} {      
         set lastime [getlaston $arg]
         set host [gethosts $arg]
         set info [getinfo $arg]
         set email [getemail $arg]
         set signoffmsg [getxtra $arg]
         putserv "PRIVMSG $channel : «» X-TreMe Whois  $arg "
         putserv "PRIVMSG $channel : «» Handle:  $arg "
         putserv "PRIVMSG $channel : «» Flags:  [chattr $arg]"
         putserv "PRIVMSG $channel : «» Known Hosts:  $host "
         if {$info == ""} {
         } else {
          putserv "PRIVMSG $channel : «» Info:  $info "
        }
        if {$email == ""} {
        } else {      
        putserv "PRIVMSG $channel : «» E-mail Address:  $email "
        }
        if {[hand2nick $arg $channel] == ""} {
          } else {
          set hander [hand2nick $arg $channel]
          putserv "PRIVMSG $channel : «» Last Time I saw $arg was was:  [ctime $lastime] "
          if {$signoffmsg == ""} {
          } else {
              putserv "PRIVMSG $channel : «» Sign Off Msg:  $signoffmsg "
          }
          putserv "PRIVMSG $channel : «» $arg is on as $hander. "
          if {[getchanidle $hander $channel] == 0} {
          } else {
            putserv "PRIVMSG $channel : «» Idle Time:  [getchanidle $hander $channel] minutes  "
          }
        }
        if {[matchattr $arg m] == 1} {
           putserv "PRIVMSG $channel : «»  $arg is My Master.   "
        }
        if {[matchattr $arg b] == 1} {
        putserv "PRIVMSG $channel : «»  $arg is another Bot.   "
        set da_chans ""
        for {set chanlinfo 0} {$chanlinfo < [llength [channels]]} {incr chanlinfo} {
        set channel3 [lindex [channels] $chanlinfo]
        if {[onchan $arg $channel3]} {
         append da_chans " " $channel3
        } 
        }
        if {$da_chans == { }} {
           putserv "PRIVMSG $channel : «»  $arg isnt around..(as far as i can see) .   "
           return 0
        } else {
           putserv "PRIVMSG $channel : «»  $arg is On channel(s) $da_chans .   "
           return 0
        }
           return 0
       }
           return 0
      }
         if {[onchan $arg $channel2]} {
   if {[validuser [nick2hand $arg $channel2]]} {
         set whoi $arg
         set arg [nick2hand $arg $channel2]
         set lastime [getlaston $arg]
         set host [gethosts $arg]
         set info [getinfo $arg]
         set email [getemail $arg]
         set signoffmsg [getxtra $arg]
         putserv "PRIVMSG $channel : «» X-TreMe Whois  $whoi "
         putserv "PRIVMSG $channel : «» Handle:  $arg "
         putserv "PRIVMSG $channel : «» Flags:  [chattr $arg]"
         putserv "PRIVMSG $channel : «» Known Hosts:  $host "
         if {$info == ""} {
        } else {
          putserv "PRIVMSG $channel : «» Info:  $info "
        }
        if {$email == ""} {
        } else {      
        putserv "PRIVMSG $channel : «» E-mail Address:  $email "
        }
        if {[hand2nick $arg $channel] == ""} {
        } else {
          set hander [hand2nick $arg $channel]
          putserv "PRIVMSG $channel : «» $arg is on as $hander. "
          putserv "PRIVMSG $channel : «» Last Time I saw $arg was was:  [ctime $lastime] "
          if {$signoffmsg == ""} {
          } else {
              putserv "PRIVMSG $channel : «» Sign Off Msg:  $signoffmsg "
          }
          if {[getchanidle $hander $channel2] == 0} {
          } else {
            putserv "PRIVMSG $channel : «» Idle Time:  [getchanidle $hander $channel] minutes  "
          }
        }
        if {[matchattr $arg m] == 1} {
           putserv "PRIVMSG $channel : «»  $arg is My Master.   "
        }
        set da_chans ""
        set da_chans2 ""
        for {set chanlinfo 0} {$chanlinfo < [llength [channels]]} {incr chanlinfo} {
        set channel3 [lindex [channels] $chanlinfo]
        if {[onchan $whoi $channel3]} {
        append da_chans " "  $channel3
        } 
       }
        if {$da_chans == { }} {
           putserv "PRIVMSG $channel : «»  $arg isnt around as far as i can see! Ive looked on $da_chans2 .   "      
           return 0
        } else {
           putserv "PRIVMSG $channel : «»  $arg is On channel(s) $da_chans .   "
           return 0
       }
           return 0
      }
     } else {
     }
    }
        putserv "PRIVMSG $channel : «»  $arg is Not a known User..   "
           return 0
   }
#Change an existing users attributes
proc pub_do_chattr {nick host handle channel arg} {
set who [lindex $arg 0]
set why [lindex $arg 1]
if {$who == ""} {
putserv "NOTICE $nick :Usage: flags <nick> <attributes.>"
return 1
}
if {$why == ""} {
putserv "NOTICE $nick :$who 's Flags are currently [chattr $who]"
return 1
}
if {[matchattr $who +n]} {
putserv "NOTICE $nick : «» X-TreMe Status: You *MAY NOT* change the owners attributes Dick Sweat! «» "
return 1
}

chattr $who $why
putserv "NOTICE $nick : «» X-TreMe Status: $who 's Flags set to [chattr $who] . «» "
putlog "«» X-TreMe Status: $nick made me change $who's attributes to $why on $channel «» "
putserv "NOTICE $who : «» X-TreMe Status: $nick Attributes on $channel set to [chattr $who] «» "
return 1
}
#End of pub_do_chattr
#Bankick someone. 
proc pub_do_ban {nick host handle channel arg} {
global botnick
set why [lrange $arg 1 end]
set who [lindex $arg 0]
set ban [maskhost [getchanhost $who $channel]]
regsub {\*!} $ban \*!\* da_ban
set ban $da_ban
set n2hand [nick2hand $who $channel]
if {[string tolower $who] == [string tolower $botnick]} {
putserv "MODE $channel -o $nick"
putserv "PRIVMSG $channel :WTF?!?! I may be a bot but even I am not that stupid!"
putserv "KICK $channel $nick :«» uhh..blow me «»"
return 1 
}
if {$who == ""} {
putserv "NOTICE $nick :Usage: BK <nick to ban and kick>"
return 1
}
if {![onchan $who $channel]} {
putserv "NOTICE $nick : «» X-TreMe Status:  $who is not currently on $channel «» "
return 1
}
if {[matchattr $n2hand m]} {
set reas "«» BK My Master? «»"
addban $ban $channel $reas 
putserv "KICK $channel $nick :$reas"
return 1
}
addban $ban $channel $why
putserv "KICK $channel $who :$why"
putlog "$nick made me ban $who who was $ban and the reason was $why."
putserv "NOTICE $nick : «» X-TreMe Status: Kick and Banned $who on $channel, with reason: $why. «» "
return 1
}
#End of pub_do_ban

proc just_left {nick uhost handle channel} {
     global botnick
        if {$nick == $botnick} {
        } else {
          if {$handle == ""} {
        } else {
          setxtra $handle "Left $channel Without Reason."
          setlaston $handle
          save
        }
       }
} 

proc set_part_reason {nick uhost handle channel partmsg} {
     global botnick
     if {$nick == $botnick} {
     } else {
       if {$handle == ""} {
       } else {
         setxtra $handle $partmsg
         setlaston $handle
         save 
      }
     }  
}

#Publically ping the bot
proc pub_do_ping {nick host handle channel arg} {
putserv "PRIVMSG $channel : «» PONG! «» "
return 1
}
#end of pub_do_ping
#pub Status
proc flag_note {hand idx arg} {
  set wha_flag [lindex $arg 0]
  set da_note [lrange $arg 1 end]
  if {$wha_flag == "" || $da_note == ""} {
    putdcc $idx "### USAGE: .flagnote <flag> <message>"
    return 0
  }
  if {
    $wha_flag != "k" && $wha_flag != "o" && $wha_flag != "j" &&
    $wha_flag != "f" && $wha_flag != "c" && $wha_flag != "n" &&
    $wha_flag != "m" && $wha_flag != "d" && $wha_flag != "x" &&
    $wha_flag != "p"} {
      putdcc $idx "### Flag \002 +$wha_flag \002 is not a User Defined Flag."
      return 0
    }
  set flagnote_userlist [userlist $wha_flag]
  set topnum [llength $flagnote_userlist]
  putdcc $idx "### Writing note To The users with \002 +$wha_flag \002 Flag. There are \002 $topnum \002 users with this Flag."
  set counter 0
  while {$counter != $topnum} {
    set to_user [lindex $flagnote_userlist $counter]
    if {![matchattr $to_user b]} {
      sendnote $hand $to_user "\002 To: +$wha_flag Users: \002 $da_note"
    }
    incr counter 1
  }
  return 0
}
proc pub_do_status {nick host handle channel arg} {
global botnick
global server
global savedchans
global chanfile
global defchanoptions
set owr ""
if {[matchattr $nick +m]} {
set owr "(My Master)"
}
if {[matchattr $nick +n]} {
set owr "(My Owner)"
}
putserv "PRIVMSG $channel : «» X-TreMe Status Requested By $nick ($handle) $owr  "
putserv "PRIVMSG $channel : «» Hello $channel I am $botnick,  BoMeRs Eggdrop Bot. "
putserv "PRIVMSG $channel : «» The Current Time in my Time Zone is [time] [date]. "
putserv "PRIVMSG $channel : «» I am Currently on $server  "
putserv "PRIVMSG $channel : «» I am set to Enforce [channels] "
putserv "PRIVMSG $channel :    "
putserv "sleep 3"
  if {[catch {set fd [open $chanfile r]}] != 0} {
    putserv "PRIVMSG $channel : «» I Cannot currently open the Channel File. Please Try again Later. «» "
    return 0
  }
  set savedchans { }
  while {![eof $fd]} {
    set savedchans [lappend savedchans [string trim [gets $fd]]]
  }
  close $fd
  set savedchans [lreplace $savedchans end end]
  if ([llength $savedchans]) {
    foreach channelinfo $savedchans {
      set channel2 [lindex $channelinfo 0]
      set modes [lindex $channelinfo 1]
      foreach mode $modes {
      set neop ""
      }
      putserv "PRIVMSG $channel : «» $channel2 «» modes - \"$modes\" . "
      if {![onchan $botnick $channel2]} {
      if {![botisop $channel2]} {
      set neop "(Need Ops)"
      }
      putserv "PRIVMSG $channel : «» Im Not Currently in $channel2. (banned or +i) "
      }
     set neop "(Im Channel Op!)"
     if {![botisop $channel2]} {
     set neop "(Need Ops)"
     }
     putserv "PRIVMSG $channel : «» Currently Enforcing $channel2 - [llength [chanlist $channel2]] Members, $neop "
     putserv "PRIVMSG $channel :   "
     putserv "sleep 2"
     }
     putserv "PRIVMSG $channel : «» X-TreMe TCL By BoMeR ! "
     return
}
##}
##}
proc msg_cycle {nick host handle arg} {
global botnick
set channel [lindex $arg 0]
set pass [lrange $arg 1 end]
if {$pass == ""} {
   putserv "NOTICE $nick :USEAGE:  /msg $botnick cycle $channel <password> "
   return 0
}
   if {![passwdOk $handle $pass]} { 
   putserv "NOTICE $nick :Access Denied"
   return 0
}
putcmdlog "($nick ! $host) !$handle! Made me Cycle $channel."
putserv "PART $channel"
putserv "JOIN $channel"
utimer 90 ""
if {![onchan $botnick $channel]} {
putserv "NOTICE $nick : «»  X-TreMe Status: I Couldn't Re-Join $channel! «» "
return 1
}
putserv "NOTICE $nick : «»  X-TreMe Status: I have sucessfully Cycled $channel "
return 1
}
#end of msg_Cycle
#Publically cycle
proc pub_cycle {nick host handle channel arg} {
global botnick
putserv "PART $channel"
putserv "JOIN $channel"
putserv "sleep 4"
if {![onchan $botnick $channel]} {
putserv "NOTICE $nick : «»  X-TreMe Status: I Couldn't Re-Join $channel! «» "
return 1
}
putserv "NOTICE $nick : «»  X-TreMe Status: I have sucessfully Cycled $channel "
return 1
}
#end of pub_Cycle
#Save :)
proc pub_do_save {nick host handle channel arg} {
save
putserv "NOTICE $nick : «» X-TreMe Status: Saved "
putlog "$nick made me Save."
return 1
}
#end of pub_do_save
#Change topic on channel
proc pub_do_topic {user host handle channel arg} {
set what [lrange $arg 0 end]
if {$what == ""} {
putserv "NOTICE $user :Usage: TOPIC <Topic you want.>"
return 1
}
if {![botisop $channel]} {
putserv "NOTICE $nick :  «» X-TreMe Status: I am not currently opped on $channel «» "
return 1
} 
putserv "TOPIC $channel :$what"
return 1
}
#end of do topic
#Delete a user from the records.
proc pub_do_del {nick host handle channel arg} {
set who [lindex $arg 0]
set usho [maskhost [getchanhost $who $channel]]
if {[matchattr $who +n]} {
putserv "MODE $channel -o $nick"
putserv "PRIVMSG $channel : «» X-TreMe Status: UNAUTHORIZED ACCESS TO DELETE USER ATTEMPTED BY $nick!!, (kicking) «» "
putserv "KICK $channel $nick : «» Attempted to Delete Owner! «»  "
return 1
}
if {$who == ""} {
putserv "NOTICE $nick :Usage: DEL <User to Delete>"
return 1
}
deluser  $who 
putlog "$nick made me Delete $who from User-Database."
return 1
}
#end of pub_do_del
#op yourself
proc pub_do_up {nick host handle channel arg} {
global botnick
if {![isop $botnick $channel]} {
putserv "NOTICE $nick : «» X-TreMe Status: I am not NOT Opped on $channel! «» "
return 1
}
if {[isop $nick $channel]} {
putserv "NOTICE $nick : «»  X-TreMe Status: You Are allready Opped!  «» "
return 1
}
putserv "MODE $channel +o $nick"
return 1
}
#end of Pub Up
#op yourself
proc pub_do_up {nick host handle channel arg} {
global botnick
if {![isop $botnick $channel]} {
putserv "NOTICE $nick : «» X-TreMe Status: I am not NOT Opped on $channel! «» "
return 1
}
if {[isop $nick $channel]} {
putserv "NOTICE $nick : «»  X-TreMe Status: You Are allready Opped!  «» "
return 1
}
putserv "MODE $channel +o $nick"
return 1
}
#end of Pub op
#give ops
proc pub_do_op {nick host handle channel arg} {
global botnick
set who [lindex $arg 0]
if {$who == ""} {
putserv "NOTICE $nick :Usage: OP <Nick to Give ops>"
return 1
}
if {![isop $botnick $channel]} {
putserv "NOTICE $nick : «» X-TreMe Status: I am not NOT Opped on $channel! «» "
return 1
}
if {[isop $who $channel]} {
putserv "NOTICE $nick : «»  X-TreMe Status: $who is allready Opped!  «» "
return 1
}
putserv "MODE $channel +o $who"
return 1
}
#end of Pub op
#Deop someone.
proc pub_do_deop {nick host handle channel arg} {
global botnick
set who [lindex $arg 0]
set n2hand [nick2hand $who $channel]
if {$who == ""} {
putserv "NOTICE $nick :Usage: DEOP <Nick to Deop>"
return 1
}
if {![isop $botnick $channel]} {
putserv "NOTICE $nick : «» X-TreMe Status: I am not NOT Opped on $channel! «» "
return 1
}
if {[string tolower $who] == [string tolower $botnick]} {
putserv "MODE $channel -o $nick"
putserv "KICK $channel $nick : «» Get Real. «» "
return 1
}
if {[matchattr $n2hand m]} {
putserv "MODE $channel -o $nick"
putserv "KICK $channel $nick : «» Deop This! «» "
return 1
}
if {![isop $who $channel]} {
putserv "NOTICE $nick : «»  X-TreMe Status: That User is NOT Opped!  «» "
return 1
}
putserv "MODE $channel -o $who"
return 1
}

proc pub_do_kick {nick host handle channel arg} {
global botnick
set who [lindex $arg 0]
set why [lrange $arg 1 end]
set n2hand [nick2hand $who $channel]
if {![onchan $who $channel]} {
putserv "NOTICE $nick : «» X-TreMe Status: $who isn't on $channel  «» "
return 1
}
if {[string tolower $who] == [string tolower $botnick]} {
putserv "KICK $channel $nick : «» Dumbass «» "
return 1
}
if {$who == ""} {
putserv "NOTICE $nick :USEAGE: K <nick to kick> <reason>"
return 1
}
if {$who == $nick} {
putserv "KICK $channel $nick : «» If you say so «» "
return 1
}
if {[matchattr $n2hand n]} {
putserv "KICK $channel $nick : «» Not gonna kick my owner «» "
return 1
}
if {$why == ""} {
putserv "KICK $channel $who : «» Requested by $nick «» "
putserv "NOTICE $nick : «» X-TreMe Status: Kicked $who from '$channel' "
return 1
}
putserv "KICK $channel $who : «» $why «» "
putserv "NOTICE $nick : «» X-TreMe Status: Kicked $who from '$channel'; Reason : $why "
return 1
}
#End of pub_do_kick
#permban someone
proc pub_do_pban {nick host handle channel arg} {
global botnick
set why [lrange $arg 1 end]
set who [lindex $arg 0]
set n2hand [nick2hand $who $channel]
set ban [maskhost [getchanhost $who $channel]]
regsub {\*!} $ban \*!\* da_ban
set ban $da_ban
if {$who == ""} {
putserv "NOTICE $nick :Usage: SHIT <Nick to shitlist>"
return 1
}
if {![onchan $who $channel]} {
putserv "NOTICE $nick : «» X-TreMe Status: $who is currently not on $channel «» "
return 1
}
if {[string tolower $who] == [string tolower $botnick]} {
putserv "KICK $channel $nick : «» Dumbass Detection «» "
return 1
}
if {[matchattr $n2hand m]} {
putserv "NOTICE $who : «» X-TreMe Status: $nick tried to shitlist you. "
putserv "NOTICE $nick : «» X-TreMe Status: You tried to shitlist $who, He is an OWNER. He's gonna have to beat the shit out of you now. You might be added to my Perm Ban List. «» "
set reas " «» Shitlist My Master? «» "
addban $ban $channel $reas
putserv "KICK $channel $nick : «» Shitlist My Master? «» "
return 1
}

addglban $ban $why
putserv "KICK $channel $who : «» $why «» "
putlog "$nick made me permban $who who was $ban and the reason was $why."
putserv "NOTICE $nick : «» X-TreMe Status: PermBanned $who on $channel. Reason: '$why'. "
return 1
}
#end of pub_do_pban
#Set the bot away. (Helps hide from ircops :))
proc pub_do_away {nick host handle channel arg} {
set why [lrange $arg 0 end]
if {$why == ""} {
putserv "NOTICE $nick :Usage: AWAY <The away msg you want me to use.>"
return 1
}
putserv "AWAY :$why"
putserv "NOTICE $nick : «» X-TreMe Status: I am Set Away. MSG set to '$why'. "
return 1
}
#end of pub_do_away
#Make the bot MSG someone...
proc pub_do_msg {nick host handle channel arg} {
set who [lindex $arg 0]
set why [lrange $arg 1 end]
if {$who == ""} {
putserv "NOTICE $nick :Usage: MSG <nick to msg> <What to say>"
return 1
}
putserv "PRIVMSG $who :$why"
putserv "NOTICE $nick : «» X-TreMe Status: Messaged $who with text '$why' "
return 1
}
#end of pub_do_msg
#Add a user to the bot
proc pub_add_user {nick host handle channel arg} {
set who [lindex $arg 0]
set what [maskhost [getchanhost $who $channel]]
if {![onchan $who $channel]} {
putserv "NOTICE $nick : «» X-TreMe Status: $who isnt on $channel «» "
return 1
}
if {$who == ""} {
putserv "NOTICE $nick :Usage: ADDUSER <User to Add.>"
return 1
}
adduser $who $what
putserv "NOTICE $nick : «» X-TreMe Status: Added $who to User-Database «» "
return 1
}
#end of pub_add_user
#lil help
proc pub_do_help {nick host handle channel arg} {
global botnick
putserv "Sleep 7"
putserv "NOTICE $nick : «»  X-TreMe Commands For $botnick (Most are DCC Commands)  «» "
putserv "NOTICE $nick : «»  CHAT <start DCC Chat>   UP <op yourself>  «» "
putserv "NOTICE $nick : «»  DEOP    MODE <channel modes>   TOPIC <change topic>  «» "
putserv "NOTICE $nick : «»  SHIT <perm ban>     ADDUSER  «» "
putserv "NOTICE $nick : «»  K <kick>   -BK <Temp Ban and Kick>  DEL <delete user>  «» "
putserv "NOTICE $nick : «»  SAY <text to say>   PING <test my lag>  «» "
putserv "NOTICE $nick : «»  AWAY <mark me as away>   SENDNOTE <send a note to someone>  «» "
putserv "NOTICE $nick : «»  MSG <nick> <what to say>  SETMODE <chan> <+bitch -autoop etc.>  «» "
putserv "sleep 2"
putserv "NOTICE $nick : «»  MOP , MDEOP , or MKICK <optional hostmask>  «» "
putserv "NOTICE $nick : «»  In DCC Chat Type .xthelp For a complete list of Help  «» "
return 1
}
#end of help
#Change the mode in the channel
proc pub_do_mode {nick host handle channel arg} {
set who [lindex $arg 0]
if {![botisop $channel]} {
putserv "NOTICE $nick : «» X-TreMe Status: I am not currently opped in $channel «» "
return 1
}
if {$who == ""} {
putserv "NOTICE $nick :Usage: MODE <Channel mode you want to set>"
return 1
}
putserv "MODE $channel $who"
return 1
}
#end of pub_do_mode
#set info
proc pub_do_sinfo {nick host handle channel arg} {
set who [lindex $arg 0]
set inf [getinfo $who]
set why [lrange $arg 1 end]
if {$who == ""} {
putserv "NOTICE $nick :Usage INFO <nick> <What info you want them to have>"
return 1
}
if {![validuser $who]} {
putserv "NOTICE $nick : «» X-TreMe status: $who isn't a valid user «» "
return 1
}
setinfo $who $why
putserv "NOTICE $nick : «» X-TreMe Status: Info for $who changed to $why «» "
putserv "NOTICE $who : «» X-TreMe Status: $nick Set your info to $why. Your info used to be ($inf) «» " 
return 1 
}
#End of set info
proc pub_do_setcom {nick host handle channel arg} {
set who [lindex $arg 0]
set inf [getcomment $who]
set why [lrange $arg 1 end]
if {$who == ""} {
putserv "NOTICE $nick :Usage -INFO <nick> <What info you want them to have>"
return 1
}
if {![validuser $who]} {
putserv "NOTICE $nick : «» X-TreMe Status: $who isn't a valid user «» "
return 1
}
setcomment $who $why
putserv "NOTICE $nick : «» X-TreMe Status: Info for $who changed to $why «» "
putserv "NOTICE $who : $nick Set your info to $why. Your info used to be ($inf) "
return 1
}
#End of set-comment 
#channels the bot is monitoring
proc pub_do_chans {nick host handle channel arg} {
set chans [channels]
putserv "NOTICE $nick : «» X-TreMe Status: I am currently on : $chans  «» "
return 1
}
#change channel settings
proc pub_do_ccs {nick host handle channel arg} {
global botnick
set who [lindex $arg 0]
set why [lrange $arg 1 end]
if {$who == ""} {
putserv "NOTICE $nick :Usage :SETMODE <channel> <settings> :Valid settings are + means yes, - means no :autoop, clearbans, enforcebans, dynamicbans, userbans, bitch, greet, stopnethack,revenge, protectops and statuslog. " 
return 1
}
if {![onchan $botnick $who]} { 
putserv "NOTICE $nick : «» X-TreMe Status: I am not currently on $who «» "
return 1
}
channel set $who $why
putserv "NOTICE $nick : «» X-TreMe Status: Changed settings on $who to $why «» "
return 1
}
#End of channel settings
#Channel info
proc pub_chan_inf {nick host handle channel arg} {
global botnick
set who [lindex $arg 0]
set ops [channel info $who]
if {![onchan $botnick $who]} {
putserv "NOTICE $nick : «» X-TreMe Status: I am not currently on $who «» "
return 1
}
putserv "NOTICE $nick : «» X-TreMe Status: channel options for $who :$ops. "
return 1
}
#end of channel info
proc pub_do_srv {nick host handle channel arg} {
global server
putserv "PRIVMSG $channel : «» X-TreMe Status: I'm currently on $server «» "
return 1
}
#end of server.
#time.
proc pub_do_tim {nick host handle channel arg} {
set who [time]
putserv "PRIVMSG $channel : «» X-TreMe Status: The current time is $who  «» "
return 1
}
#end of time :)
#version 
proc pub_say_ver {nick host handle channel arg} {
global version
putserv "PRIVMSG $nick : «» I'm an Egg-Drop Bot, And a X-TreMe TCL Script Interacting together.!! «» "
return 1
}
#end of ver.
#Make the bot jump servers.
proc pub_do_jump {nick host handle channel arg} {
set who [lindex $arg 0]
set pt [lindex $arg 1]
set pswd [lindex $arg 2]
if {$who == ""} {
putserv "NOTICE $nick :Usage: jump <server> & <port> <password> if necessary"
return 1
}
putserv "NOTICE $nick : «» Jumping Servers «» "
putserv "NOTICE $nick : «» $who $pt $pswd  «» "
jump $who $pt $pswd
return 1
}
#End of Jump
#Send a note to another user
proc pub_do_note {nick host handle channel arg} {
set who [lindex $arg 0]
set whom [lindex $arg 1]
set what [lrange $arg 2 end]
if {![validuser $who]} {
putserv "NOTICE $nick : «» X-TreMe Status: $who isnt a valid user «» "
return 1
}

if {![validuser $whom]} {
putserv "NOTICE $nick : «» X-TreMe Status: $who isnt a valid user. «» "
return 1
}
if {$whom == ""} {
putserv "NOTICE $nick :Usage: SENDNOTE <from who> <to who> <note>"
return 1
}
set from "Public Note Sent from $nick!uhost on $channel at [time] --"
sendnote $who $whom $what
putserv "NOTICE $nick : «» X-TreMe Status: message from $who to $whom with the note '$what'. " 
return 1
}
#End of SendNote
#Link to a known tandem bot
proc pub_do_link {nick host handle channel arg} {
set who [lindex $arg 0]
set why [lindex $arg 1]
if {![validuser $who]} {
putserv "NOTICE $nick : «» X-TreMe Status: Either $who isnt a BOT, or is not setup to be one. «» "
return 1
}
link $who $why
putserv "NOTICE $nick : «» X-TreMe Status: Attempting to link to $why via $who. «» "
return 1
}
#end of attempt link :)
#make the bot tell you the date
proc pub_do_dat {nick host handle channel arg} {
set who [date]
putserv "PRIVMSG $channel : «» X-TreMe Status: $who «» "
return 1
}
#end of date.

proc cleanarg {arg} {
  set response ""
  for {set i 0} {$i < [string length $arg]} {incr i} {
    set char [string index $arg $i]
    if {($char != "\12") && ($char != "\15")} {
      append response $char
    }
  }
  return $response
}

set savedchans { }
set okchanmodes {+clearbans -clearbans +enforcebans -enforcebans +dynamicbans -dynamicbans +userbans -userbans +autoop -autoop +bitch -bitch +greet -greet +protectops -protectops +revenge -revenge +stopnethack -stopnethack +statuslog -statuslog}
set goodchanmodes {+i +m +n +s +t +p -i -m -s -p}
proc getchanmode2 {channel} {
  global savedchans
  for {set i 0} {$i < [llength $savedchans]} {incr i} {
    set this [lindex $savedchans $i]
    if {[string compare [string tolower [lindex $this 0]] [string tolower $channel]] == 0} {
      return [lindex $this 1]
    }
  }
  return ""
}

proc getchantopic {channel} {
  global savedchans
  for {set i 0} {$i < [llength $savedchans]} {incr i} {
    set this [lindex $savedchans $i]
    if {[string compare [string tolower [lindex $this 0]] [string tolower $channel]] == 0} {
      return [lindex $this 2]
    }
  }
  return ""
}
 
proc setchanmode {channel data} {     
  global savedchans
  for {set i 0} {$i < [llength $savedchans]} {incr i} {
    set this [lindex $savedchans $i]
    if {[string compare [string tolower [lindex $this 0]] [string tolower $channel]] == 0} {
      set topic [lindex $this 2]
      set dchanmodes [lindex $this 3]
      set this [list $channel $data $topic $dchanmodes]
      set savedchans [lreplace $savedchans $i $i $this]
      savechans
      return 0
    }
  }
}

proc setchanmode2 {channel data dchanmodes} {     
  global savedchans
  for {set i 0} {$i < [llength $savedchans]} {incr i} {
    set this [lindex $savedchans $i]
    if {[string compare [string tolower [lindex $this 0]] [string tolower $channel]] == 0} {
      set topic [lindex $this 2]
      set this [list $channel $data $topic $dchanmodes]
      set savedchans [lreplace $savedchans $i $i $this]
      savechans
      return 0
    }
  }
}

### DCC CHAT

proc msg_chat {nick uhost hand arg} {
  global telnet
  if {$telnet == 0} {
    putserv "PRIVMSG $nick : «»  Sorry,  Your Host is not Reachable at this time. please try again later. «» "
    return 0
  }
  putserv "PRIVMSG $nick :\001DCC CHAT chat [myip] $telnet\001"
  return 1
}
## DCC CHAT
proc setchantopic {channel data} {     
  global savedchans
  for {set i 0} {$i < [llength $savedchans]} {incr i} {
    set this [lindex $savedchans $i]
    if {[string compare [string tolower [lindex $this 0]] [string tolower $channel]] == 0} {
      set modes [lindex $this 1]
      set this [list $channel $modes $data]
      set savedchans [lreplace $savedchans $i $i $this]
      savechans
      return 0
    }
  }
}

proc savechans {} {
  global savedchans
  global chanfile
  set fd [open $chanfile w]
  foreach channelinfo $savedchans {
    puts $fd $channelinfo
  }
  close $fd
  return
}

proc loadchans {} {
  global savedchans
  global chanfile
  global botnick
  global defchanoptions
  putlog " «»                                        "
  putlog " «»  Status: X-TreMe TCL by BoMeR Loaded.  "
  putlog " «»                                        "
  if {[catch {set fd [open $chanfile r]}] != 0} {
    setconfigchans
    putlog " «»  channel file $chanfile does not exist! "
    return 0
  }
  set savedchans { }
  while {![eof $fd]} {
    set savedchans [lappend savedchans [string trim [gets $fd]]]
  }
  close $fd
  set savedchans [lreplace $savedchans end end]
  if ([llength $savedchans]) {
    foreach channelinfo $savedchans {
      set channel [lindex $channelinfo 0]
      set modes [lindex $channelinfo 1]
      set topic [lindex $channelinfo 2]
      set chanmodez [lindex $channelinfo 3]
      if {$chanmodez == { }} { 
      set chanmodez $defchanoptions
      } else {
      set who [lindex $chanmodez 0]
      set wha [lindex $chanmodez 1]
      set defchanoptions "chanmode $who idle-kick $wha"
      }      
      set needop "need-op \{\}"
      set needinvite "need-invite \{\}"
      set options [concat $defchanoptions $needop $needinvite]
      set neeop "(Enforcing)"
      channel add $channel $options
      foreach mode $modes {
       channel set $channel $mode
      }
      if {$topic != ""} {
        putserv "TOPIC $channel :$topic"
  }
  if {![onchan $botnick $channel]} { set neeop "(Joining) " }
      putlog " «» Added saved channel $channel $neeop "
 }
}
if {($savedchans == { }) && ([llength [channels]] > 0} {
    setconfigchans
  }
  return
}

proc setconfigchans {} {
  global savedchans
  foreach channel [channels] {
   set chanmodes [lrange [channel info $channel] 4 end]
    set savit $channel
    lappend savit $chanmodes ""
    lappend savedchans $savit
  }
  savechans
  return 1
}

proc addchannel {channel chanmodes topic} {
  global defchanoptions savedchans
  if {[lsearch [string tolower [channels]] [string tolower $channel]] >= 0} {return 0}
  set needop "need-op \{\}"
  set needinvite "need-invite \{\}"
  set defchanoptions {chanmode "+snt-pm" idle-kick 0}
  set dchanoptions $defchanoptions
  set options [concat $dchanoptions $needop $needinvite]
  channel add $channel $options
  foreach option $chanmodes {
    channel set $channel $option
  }
  if {$topic != ""} {
    putserv "TOPIC $channel :$topic"
  }
  lappend channel $chanmodes $topic "[lindex $dchanoptions 1] [lindex $dchanoptions 3]"
  lappend savedchans $channel
  savechans
  return 1
}

proc remchannel {channel} {
  global savedchans
  if {[lsearch [string tolower [channels]] [string tolower $channel]] == -1} {return 0}
  if ([llength $savedchans]) {
    set index 0
    foreach channelinfo $savedchans {
      set ochannel [lindex $channelinfo 0]
      if {[string tolower $ochannel] == [string tolower $channel]} {
        set savedchans [lreplace $savedchans $index $index]
        channel remove $channel
        savechans
        return 1
      }
      incr index
    }
  }
  return 0
}

proc dcc_botjoin {handle idx channel} {
  global defchanmodes
  if {([llength $channel] != 1) || ([string first # $channel] == -1)} {
    putdcc $idx "syntax: .join #channel"
    return 0
  }
  if {[addchannel $channel $defchanmodes ""]} {
    putcmdlog " «» X-TreMe Status: I have joined $channel - requested by $handle  «» "
  } else {
    putdcc $idx " «» X-TreMe Status: I'm already on $channel! «» "
  }
  return 0
}

##############################

proc dcc_botcycle {handle idx channel} {
  global defchanmodes
  global botnick
  if {([llength $channel] != 1) || ([string first # $channel] == -1)} {
    putdcc $idx "syntax: .cycle #channel"
    return 0
  }
  if {![onchan $botnick $channel]} {
putdcc $idx " «»  X-TreMe Status: Im not on $channel! «» "
return 1
  } else {
  putserv "PART $channel"
  putserv "JOIN $channel"
putserv "sleep 6"
  if {![onchan $botnick $channel]} {
putdcc $idx " «»  X-TreMe Status: I Couldn't Re-Join $channel! «» "
return 0
}
putdcc $idx " «»  X-TreMe Status: I have sucessfully Cycled $channel "
  return 0
  }
}
###########################################
  
proc dcc_botleave {handle idx channel} {
  if {([llength $channel] != 1) || ([string first # $channel] == -1)} {
    putdcc $idx "USEAGE: .leave #channel"
    return 0
  }
  if {[lsearch [string tolower [channels]] [string tolower $channel]] == 0} {
    putdcc $idx " «» X-TreMe Status: I can't leave my home channel! «» "
    return 0
  }
  if {[remchannel $channel]} {
    putcmdlog "left $channel - requested by $handle"
  } else {
    putdcc $idx " «» X-TreMe Status: I am not currently on $channel! «» "
  }
  return 0
}

proc dcc_settopic {handle idx topic} {
  set channel [lindex [console $idx] 0]
  set topic [cleanarg $topic]
  if {[llength $topic] >= 1} {
    set t2 ""
    for {set i 0} {$i < [string length $topic]} {incr i} {
      set this [string index $topic $i]
      if {$this == "\""} {
        append t2 "\'"
      } {
        if {$this == "\{"} {
          append t2 "("
        } {
          if {$this == "\}"} {                     
            append t2 ")"
          } {
            append t2 $this
          }
        }
      }
    }
    set topic $t2
    putserv "TOPIC $channel :$topic"
    setchantopic $channel $topic
    putcmdlog " «» X-TreMe Status: Channel $channel default topic set to \"$topic\" by $handle «» "
    putdcc $idx "Topic set for channel $channel."
    return 0
  }
  set topic [getchantopic $channel]
  putdcc $idx " «» X-TreMe Status: Default topic for $channel is \"$topic\" «» "
  return 0
}

proc msg_botjoin {nick uhost handle arg} {
  global defchanmodes botnick
  set channel [lindex $arg 0]
  set pass [lrange $arg 1 end]
  if {([llength $channel] != 1) || ([string first # $channel] == -1)} {
    putserv "NOTICE $nick :USEAGE: /msg $botnick join #channel <password>"
    return 0
  }
  if {$pass == ""} {
   putserv "NOTICE $nick :USEAGE: /msg $botnick join $channel <password>"
   return 0
}
   if {![passwdOk $handle $pass]} { 
   putserv "NOTICE $nick :Access Denied"
   return 0
}
  if {[addchannel $channel $defchanmodes ""]} {
    putcmdlog "($nick ! uhost) !$handle! Made me Join $channel."
  } else {
    putserv "NOTICE $nick : «» X-TreMe Status: I'm already on $channel! «» "
  }
  return 0
}

proc msg_botleave {nick uhost handle arg} {
  global botnick
  set channel [lindex $arg 0]
  set pass [lrange $arg 1 end]
  if {([llength $channel] != 1) || ([string first # $channel] == -1)} {
    putserv "NOTICE $nick :USEAGE: /msg $botnick leave #channel <password>"
    return 0
  }
  if {$pass == ""} {
   putserv "NOTICE $nick :USEAGE: /msg $botnick leave <channel> <password>"
   return 0
}
   if {![passwdOk $handle $pass]} { 
   putserv "NOTICE $nick :Access Denied"
   return 0
}
  if {[lsearch [string tolower [channels]] [string tolower $channel]] == 0} {
    putserv "NOTICE $nick : «» X-TreMe Status: I can't leave my home channel! «» "
    return 0
  }
  if {[remchannel $channel]} {
    putcmdlog "($nick ! $uhost) !$handle! Made me Leave $channel."
  } else {
    putserv "NOTICE $nick : «» X-TreMe Status: I'm not on $channel! «» "
  }
  return 0
}

proc do_pinvite {handle idx arg} {
set channel [lindex [console $idx] 0]
set who [lindex $arg 0]
  if {![onchan $who $channel]} {
putdcc $idx " «»  X-TreMe Status: $who is not on $channel! «» "
return 1
}  
  global telnet
  if {$telnet == 0} {
    putdcc $idx " «»  X-TreMe Status: Telnet is not available right now =\ «» "
    return 0
  }
  putserv "NOTICE $who :$handle invites you to join the Party Line."
  putserv "NOTICE $who :If you have already introduced yourself to me please *DO NOT* Type NEW."
  putserv "PRIVMSG $who :\001DCC CHAT chat [myip] $telnet\001"
  return 1
}



proc dcc_do_mode {hand idx arg} {
  set arg [cleanarg $arg]
  set channel [lindex [console $idx] 0]
  set setmodes [channelmodechange $hand $channel $arg]
  if {$setmodes == { }} {
    set setmodes [lrange [channel info $channel] 0 1]
  } {
    putcmdlog " «» X-TreMe Status: $hand set $channel channel modes to: '$setmodes' "
  }
  putdcc $idx " «» X-TreMe Status: $channel Channel modes set to: '$setmodes' «» "
  return 0
}


#Change the mode in DCC ***************************

proc dcc_do_mode2 {handle idx arg} {
set channel [lindex [console $idx] 0]
set who [lindex $arg 0]
set when [lindex $arg 1]

if {![botisop $channel]} {
putserv "NOTICE $nick : «» X-TreMe Status: I am not currently opped in $channel «» "
return 1
}
if {$who == ""} {
putserv "NOTICE $nick :Usage: .MODE <Channel mode you want to set>"
return 1
}
putserv "MODE $channel $who $when"
return 1
}
#end of dcc_do_mode2


proc channelmodechange {handle channel modes} {
  set modes [cleanarg $modes]
  global goodchanmodes
  global savedchans
  set donemodes { }
  if {([string index $modes 0] != "+") && ([string index $modes 0] != "-")} {return [lindex [channel info $channel] 0]}
  set chanmodes [lindex [channel info $channel] 0]
      channel set $channel chanmode $modes
      lappend $donemodes $modes
      channel set $channel chanmode $modes
      set chanmodes [lrange [channel info $channel] 4 end]
      set dchanmodes "$modes 0"
      setchanmode2 $channel $chanmodes $dchanmodes
      savechans
  return $donemodes
}

proc chanmodechange {handle channel modes} {
  set modes [cleanarg $modes]
  global okchanmodes
  set donemodes { }
  set chanmodes [getchanmode2 $channel]
  if {([string index $modes 0] != "+") && ([string index $modes 0] != "-")} {return $donemodes}
  set t2 ""
  for {set i 0} {$i < [string length $modes]} {incr i} {
    set this [string index $modes $i]
    if {$this == "\""} {
      append t2 "\'"
    } {
      if {$this == "\{"} {
        append t2 "("
      } {
        if {$this == "\}"} {                     
          append t2 ")"
        } {
          append t2 $this
        }
      }
    }
  }
  set modes $t2
  for {set i 0} {$i < [llength $modes]} {incr i} {
    set mode [string tolower [lindex $modes $i]]
    if {[string match $mode "+topic"]} {
      if {[expr $i + 1] < [llength $modes]} {
        set topic [lrange $modes [expr $i + 1] end]
      } else {
        set topic ""
      }
      setchantopic $channel $topic
      putserv "TOPIC $channel :$topic"
      putcmdlog "Channel $channel default topic set to \"$topic\" by $handle."
      lappend donemodes +topic
      setchanmode $channel $chanmodes
      return $donemodes
    }
    if {[string match $mode "-topic"]} {
      setchantopic $channel ""
      putserv "TOPIC $channel :"
      putcmdlog " «» X-TreMe Status: Channel $channel default topic set to \"$topic\" by $handle."
      lappend donemodes -topic
      continue
    }
    if {[lsearch $okchanmodes $mode] != -1} {
      channel set $channel $mode
      lappend donemodes $mode
      set antimode [string trimleft $mode "+-"]
      if {[string index $mode 0] == "-"} {
        set antimode "+$antimode"
      } else {
        set antimode "-$antimode"
      }
      set index [lsearch $chanmodes $antimode]
      if {$index != -1} {
        set chanmodes [lreplace $chanmodes $index $index $mode]
      }
      setchanmode $channel $chanmodes
    }
  }
  return $donemodes
}

proc dcc_chchanmodes {hand idx arg} {
  set arg [cleanarg $arg]
  set channel [lindex [console $idx] 0]
  set setmodes [chanmodechange $hand $channel $arg]
  if {$setmodes == { }} {
    set setmodes [lrange [channel info $channel] 4 end]
  } {
    putcmdlog " «» X-TreMe Status: $hand set $channel channel modes to: '$setmodes'"
  }
  putdcc $idx " «» X-TreMe Status: $channel Channel modes set to: '$setmodes' «» "
  return 0
}

proc dcc_channels {hand idx arg} {
  putdcc $idx " «» X-TreMe Status: I'm Currently on: [channels] «» "
  return 0
}

proc msg_channels {nick uhost hand arg channel} {
  putserv "NOTICE $nick : «» X-TreMe Status: Currently on: [channels] «» "
  return 0
}

# COMMANDS
# <mask> :== <nick>!<username>@<domain>
#
# .massop <chan> <mask>
# 	requires +m, ops all +m and +o users, or it will op users matching
#       <mask> if specified, in other words it won't protect you from
#       opping an entire domain when the users are not +o or +m users.
# .massdeop <chan> <mask>
#	requires +m, deops all except +m and bot
# .masskick <chan> <mask>
#       requires +m, kicks all except +m and bot

proc mass_op {hand idx arg} {
  global server
  set oplist ""

  set chan [lindex $arg 0]
  set rest [lrange $arg 1 end]
  if {$chan == ""} {
    putdcc $idx "### What channel do you want me to preform a mass op on?"
    return 0
  }

  if {[lsearch -exact [string tolower [channels]] [string tolower $chan]] == -1} {
    putdcc $idx "###  I am NOT on that Channel!"
    return 0
  }

  if ![botisop $chan] {
    putdcc $idx "###   I am not opped in that channel!"
    return 0
  }

  if {$rest == ""} {
    putdcc $idx "### I am opping all masters and ops on ${chan}!"
    foreach nick [chanlist $chan] {
      set who [nick2hand $nick $chan]
      if {([matchattr $who m] || [matchattr $who o]) && ![isop $nick $chan]} {
	append oplist " " $nick
      }
    }
  } {
    putdcc $idx "### I am opping users matching hostmask on ${chan}: $rest"
    foreach hostmask $rest {
      foreach nick [chanlist $chan] {
        set userhost $nick
        append userhost "!" [getchanhost $nick $chan]
        set who [nick2hand $nick $chan]
        if {[string match $hostmask $userhost] && ![isop $nick $chan]} {
          append oplist " " $nick
        }
      }
    }
  }

  if {$oplist == ""} {
    putdcc $idx "### Couldn't find anyone to op"
    return 0
  }

  putdcc $idx "### Oping [llength $oplist] on ${chan}: $oplist"
  set cnt 0

  while {$cnt < [llength $oplist]} {
    putserv "MODE $chan +oooo [lindex $oplist $cnt] [lindex $oplist [expr $cnt + 1]] [lindex $oplist [expr $cnt + 2]] [lindex $oplist [expr $cnt + 3]]"
    incr cnt 4
  }
  return 1
}

proc mass_deop {hand idx arg} {
  global server botnick

  set deoplist ""

  set chan [lindex $arg 0]
  set rest [lrange $arg 1 end]
  if {$chan == ""} {
    putdcc $idx "Syntax: .massdeop #channel"
    return 0
  }

  if {[lsearch -exact [string tolower [channels]] [string tolower $chan]] == -1} {
    putdcc $idx "### I m not on that channel!"
    return 0
  }

  if ![botisop $chan] {
   putdcc $idx "### Im not opped in that channel!"
   return 0
  }

  if {$rest == ""} {
    putdcc $idx "### I am deopping everyone but my master(s) on ${chan}..."
      foreach nick [chanlist $chan] {
      set who [nick2hand $nick $chan]
      if {(![matchattr $who m] || $who == "*") && [isop $nick $chan] && $nick != $botnick} {
	append deoplist " " $nick
      }
    }
  } {
    putdcc $idx "### I am deopping users matching hostmask on ${chan}: $rest"
    foreach hostmask $rest {
      foreach nick [chanlist $chan] {
        set userhost $nick
        append userhost "!" [getchanhost $nick $chan]
        set who [nick2hand $nick $chan]
        if {[string match $hostmask $userhost] && ![matchattr $who m] && $nick != $botnick} {
          append deoplist " " $nick
        }
      }
    }
  }

  if {$deoplist == ""} {
    putdcc $idx "### Couldn't find anyone to deop"
    return 0
  }

  putdcc $idx "### Deoping [llength $deoplist] people on ${chan}: $deoplist"
  set cnt 0

  while {$cnt < [llength $deoplist]} {
    putserv "MODE $chan -oooo [lindex $deoplist $cnt] [lindex $deoplist [expr $cnt + 1]] [lindex $deoplist [expr $cnt + 2]] [lindex $deoplist [expr $cnt + 3]]"
    incr cnt 4
  }
  return 1
}

proc mass_kick {hand idx arg} {
  global server botnick

  set kicklist ""

  set chan [lindex $arg 0]
  set rest [lrange $arg 1 end]
  if {$chan == ""} {
    putdcc $idx "### What channel do you want to Mass Kick on?"
    return 0
  }

  if {[lsearch -exact [string tolower [channels]] [string tolower $chan]] == -1} {
    putdcc $idx "### Im not on that channel!"
    return 0
  }

  if ![botisop $chan] {
   putdcc $idx "### Im not opped on that channel!"
   return 0   
  }

  if {$rest == ""} {
    putdcc $idx "### I am kicking everyone who isn't a master on ${chan}..."
    foreach nick [chanlist $chan] {
      set who [nick2hand $nick $chan]
      if {(![matchattr $who m] || $who == "*") && $nick != $botnick} {
        append kicklist " " $nick
      }
    }
  } {
    putdcc $idx "### I am kicking users matching hostmask ${chan}: $rest"
    foreach hostmask $rest {
      foreach nick [chanlist $chan] {
        set userhost $nick
        append userhost "!" [getchanhost $nick $chan]
        set who [nick2hand $nick $chan]
        if {[string match $hostmask $userhost] && ![matchattr $who m] && $nick != $botnick} {
          append kicklist " " $nick
        }
      }
    }
  }

  if {$kicklist == ""} {
    putdcc $idx "### Couldn't find anyone to kick"
    return 0
  }
  putdcc $idx "### Kicking [llength $kicklist] lamers on ${chan}: $kicklist"
  set cnt 0
  while {$cnt < [llength $kicklist]} {
  set te " «» Mass Kick «» "
    putserv "KICK $chan [lindex $kicklist $cnt] $te"
    putserv "KICK $chan [lindex $kicklist [expr $cnt + 1]] $te"
    putserv "KICK $chan [lindex $kicklist [expr $cnt + 2]] $te"
    putserv "KICK $chan [lindex $kicklist [expr $cnt + 3]] $te"
    incr cnt 4
   }
  return 1
 }


proc pub_mass_op {nick host handle chan arg} {
  global server
  set oplist ""
  set rest [lrange $arg 0 end]
  if {[lsearch -exact [string tolower [channels]] [string tolower $chan]] == -1} {
    return 0
  }

  if ![botisop $chan] {
    putserv "NOTICE $nick : «» X-TreMe Status: I'm not opped in $chan! «»"
    return 0
  }
  if {$rest == ""} {
    foreach nick [chanlist $chan] {
      set who [nick2hand $nick $chan]
      if {([matchattr $who m] || [matchattr $who o]) && ![isop $nick $chan]} {
	append oplist " " $nick
      }
    }
  } {
    foreach hostmask $rest {
      foreach nick [chanlist $chan] {
        set userhost $nick
        append userhost "!" [getchanhost $nick $chan]
        set who [nick2hand $nick $chan]
        if {[string match $hostmask $userhost] && ![isop $nick $chan]} {
          append oplist " " $nick
        }
      }
    }
  }

  if {$oplist == ""} {
    putserv "NOTICE $nick : «» X-TreMe Status: I couldnt find anyone to op in $chan! «»"
    return 0
  }

  set cnt 0

  while {$cnt < [llength $oplist]} {
    putserv "MODE $chan +oooo [lindex $oplist $cnt] [lindex $oplist [expr $cnt + 1]] [lindex $oplist [expr $cnt + 2]] [lindex $oplist [expr $cnt + 3]]"
    incr cnt 4
  }
  return 1
}

proc pub_mass_kick {nick host handle chan arg} {
  global server botnick
  set kicklist ""
  set rest [lrange $arg 0 end]
  if {[lsearch -exact [string tolower [channels]] [string tolower $chan]] == -1} {
    return 0
  }
  if ![botisop $chan] {
    putserv "NOTICE $nick : «» X-TreMe Status: I'm not opped in $chan! «»"
   return 0   
  }
  if {$rest == ""} {
    foreach nick [chanlist $chan] {
      set who [nick2hand $nick $chan]
      if {(![matchattr $who m] || $who == "*") && $nick != $botnick} {
        append kicklist " " $nick
      }
    }
  } {
    foreach hostmask $rest {
      foreach nick [chanlist $chan] {
        set userhost $nick
        append userhost "!" [getchanhost $nick $chan]
        set who [nick2hand $nick $chan]
        if {[string match $hostmask $userhost] && ![matchattr $who m] && $nick != $botnick} {
          append kicklist " " $nick
        }
      }
    }
  }

  if {$kicklist == ""} {
    putserv "NOTICE $nick : «» X-TreMe Status: There is no one for me to kick in $chan! «»"
    return 0
  }
  set cnt 0
  while {$cnt < [llength $kicklist]} {
  set te "«» Mass Kick «»"
    putserv "KICK $chan [lindex $kicklist $cnt] $te"
    putserv "KICK $chan [lindex $kicklist [expr $cnt + 1]] $te"
    putserv "KICK $chan [lindex $kicklist [expr $cnt + 2]] $te"
    putserv "KICK $chan [lindex $kicklist [expr $cnt + 3]] $te"
    incr cnt 4
   }
  return 1
 }

proc pub_mass_deop {nick host handle chan arg} {
  global server botnick
  set deoplist ""
  set rest [lrange $arg 0 end]
  if {[lsearch -exact [string tolower [channels]] [string tolower $chan]] == -1} {
    return 0
  }

  if ![botisop $chan] {
    putserv "NOTICE $nick : «» X-TreMe Status: I'm not opped in $chan! «»"
   return 0
  }

  if {$rest == ""} {
      foreach nick [chanlist $chan] {
      set who [nick2hand $nick $chan]
      if {(![matchattr $who m] || $who == "*") && [isop $nick $chan] && $nick != $botnick} {
	append deoplist " " $nick
      }
    }
  } {
    foreach hostmask $rest {
      foreach nick [chanlist $chan] {
        set userhost $nick
        append userhost "!" [getchanhost $nick $chan]
        set who [nick2hand $nick $chan]
        if {[string match $hostmask $userhost] && ![matchattr $who m] && $nick != $botnick} {
          append deoplist " " $nick
        }
      }
    }
  }

  if {$deoplist == ""} {
    putserv "NOTICE $nick : «» Couldnt Find anyone to De-op! «»"
    return 0
  }
  set cnt 0

  while {$cnt < [llength $deoplist]} {
    putserv "MODE $chan -oooo [lindex $deoplist $cnt] [lindex $deoplist [expr $cnt + 1]] [lindex $deoplist [expr $cnt + 2]] [lindex $deoplist [expr $cnt + 3]]"
    incr cnt 4
  }
  return 1
}


######################################################
proc set_bot_away {} {
  global awaymsgs
  set xtra ": Away Since "
  set tim [time]
  set randtime [rand 60]
  if {$randtime == 0} {
  set randtime 5
  }
  set thenum [rand [llength $awaymsgs]]
  if [rand 13] {
  if {$thenum == 0} { 
  timer [rand 60] set_bot_away
  return
 }
    set awy [lindex $awaymsgs $thenum]
    putserv "AWAY :$awy $xtra $tim"
    } else {
    putserv "AWAY :Auto Away Engaged.. $xtra $tim"
  }
  timer [rand 60] set_bot_away
}

##################################################

proc resynch_deop {hand idx arg} {
  global server botnick

  set deoplist ""

  set chan [lindex $arg 0]
  set rest [lrange $arg 1 end]
  if {$chan == ""} {
    putdcc $idx "Syntax: .resynch #channel"
    return 0
  }

  if {[lsearch -exact [string tolower [channels]] [string tolower $chan]] == -1} {
    putdcc $idx "### I m not on that channel!"
    return 0
  }

  if ![botisop $chan] {
   putdcc $idx "### Im not opped in that channel!"
   return 0
  }

  if {$rest == ""} {
    putdcc $idx "### (Beginning Resynch)deopping everyone on ${chan}..."
      foreach nick [chanlist $chan] {
      set who [nick2hand $nick $chan]
      if {[isop $nick $chan] && $nick != $botnick} {
	append deoplist " " $nick
      }
    }
  } {
    putdcc $idx "### I am deopping All ops on ${chan}"
    foreach hostmask $rest {
      foreach nick [chanlist $chan] {
        set userhost $nick
        append userhost "!" [getchanhost $nick $chan]
        set who [nick2hand $nick $chan]
        if {[string match $hostmask $userhost] && \
        $nick != $botnick} {
          append deoplist " " $nick
        }
      }
    }
  }

  if {$deoplist == ""} {
    putdcc $idx "### Couldn't find anyone to deop! (Beginning Mass kick)"
    
   resynch_kick $hand $idx $chan
   return 0
  }

  putdcc $idx "### Deoping [llength $deoplist] people on ${chan}: $deoplist"
  set cnt 0

  while {$cnt < [llength $deoplist]} {
    putserv "MODE $chan -oooo [lindex $deoplist $cnt] [lindex $deoplist [expr $cnt + 1]] [lindex $deoplist [expr $cnt + 2]] [lindex $deoplist [expr $cnt + 3]]"
    incr cnt 4
  }
    putserv "MODE $chan +ik XTREME_RESYNCH"
resynch_kick $hand $idx $chan
  return 1
}


proc resynch_kick {hand idx chan} {
  global server botnick

  set kicklist ""
  if {$chan == ""} {
    putdcc $idx "### What channel do you want to Mass Kick on?"
    return 0
  }
  if {[lsearch -exact [string tolower [channels]] [string tolower $chan]] == -1} {
    putdcc $idx "### Im not on that channel!"
    return 0
  }

  if ![botisop $chan] {
   putdcc $idx "### Im not opped on that channel!"
   return 0   
  }
    putdcc $idx "### I am kicking everyone on ${chan}..."
    foreach nick [chanlist $chan] {
      set who [nick2hand $nick $chan]
      if {$nick != $botnick} {
        append kicklist " " $nick
      }
    }
  if {$kicklist == ""} {
    putdcc $idx "### Couldn't find anyone to kick -- (Cycling Now)"
    resynch_cycle $hand $idx $chan
  }

  putdcc $idx "### Kicking [llength $kicklist] lamers on ${chan}: $kicklist"
  set cnt 0

  while {$cnt < [llength $kicklist]} {
    set te "«» X-TreMe TCL Resynching Channel! «»"
    putserv "KICK $chan [lindex $kicklist $cnt] $te"
    putserv "KICK $chan [lindex $kicklist [expr $cnt + 1]] $te"
    putserv "KICK $chan [lindex $kicklist [expr $cnt + 2]] $te"
    putserv "KICK $chan [lindex $kicklist [expr $cnt + 3]] $te"

    incr cnt 4
  }
putdcc $idx "### Done Kicking Everyone on $chan -- (Cycling Now)"
resynch_cycle $hand $idx $chan
}

proc resynch_cycle {hand idx chan} {
  global defchanmodes
  global botnick
  if {([llength $chan] != 1) || ([string first # $chan] == -1)} {
    putdcc $idx "syntax: resynch_cycle #channel"
    return 0
  }
  if {![onchan $botnick $chan]} {
putdcc $idx "«»  X-TreMe Status: Im not on $chan! «»"
Return 1
  } else {
    putserv "PART $chan"
  putserv "JOIN $chan"
  if {![onchan $botnick $chan]} {
putdcc $idx "###  I Couldn't Re-Join $chan! «»"
return 0
}
putdcc $idx "###  I have sucessfully Cycled $chan (Resynch Complete!)"
  return 0
  }
}

proc pub_show_channel {nick host handle channel arg} {
set chan [lindex $arg 0]
if {$chan == "" } {set chan $channel}
  if {[lsearch -exact [string tolower [channels]] [string tolower $chan]] == -1} {
    putserv "PRIVMSG $nick :\002 «» Im Not on that channel! «» \002"
    return 0
  }

set i 1
    putserv "PRIVMSG $channel :Channel $chan , [llength [chanlist $chan]] members, mode [getchanmode $chan]"
    putserv "PRIVMSG $channel :    NICKNAME  HANDLE    JOINED  STAT USER@HOST"
    putserv "PRIVMSG $channel :(I = idle, M = master, O = op, D = deop)"
    append it "." 
    foreach nick [chanlist $chan] {
    set who [nick2hand $nick $chan]
    set it $i
    append it "."
    set da_msg ""
    set the_flags1 ""
    set the_flags2 ""
    set the_flags3 ""
    set the_flags4 ""
    set the_flags5 ""
    set ctimer "18:00:00"
    set ctimer [lindex [ctime [getlaston $who]] 3]
    if {$ctimer == "18:00:00"} {
    set ctimer "dunno"
    }
    if {[isop $nick $chan]} {set da_msg "@"}
    if {[matchattr $who m]} {set the_flags1 "M"}
    if {[matchattr $who o]} {set the_flags2 "O"}
    if {[matchattr $who d]} {set the_flags5 "D"}
    if {[getchanidle $nick $chan] >= 5 } {set the_flags4 "I"}
    append the_flags3 $the_flags4 $the_flags5 $the_flags1 $the_flags2 
    append da_msg $nick
    putserv "PRIVMSG $channel :$it $da_msg  $who  \($ctimer\)  $the_flags3  [getchanhost $nick $chan]"
    set it ""
    incr i 1
    }
    putserv "PRIVMSG $channel :End of channel info."
    return
    }
#### TOPIC STuff

# topic refresh time, in minutes
set topic_refresh_rate 90

bind msg - topic msg_topic

proc set_topic {} {
  global random_topic topics_changed topic_refresh_rate

  if {$topics_changed == 1} {
     putlog " «» Writing topics file... «» "
     topic_write
  }

  foreach i [array names random_topic] {
     if {[lsearch -exact [string tolower [channels]] [string tolower $i]] != -1} {
        set topic [lindex $random_topic($i) [rand [llength $random_topic($i)]]]
        putserv "TOPIC $i :$topic"
     } {
        unset random_topic($i)
     }
  }
  timer $topic_refresh_rate set_topic
}

proc sync_topic {} {
  set time_ending [string range [time] 2 4]
  if { $time_ending == ":00" } {
    set_topic
  } {
    timer 1 sync_topic
  }
}

proc topic_show {nick uhost hand arg} {
  global random_topic botnick

  set channel [lindex $arg 0]
  if {$channel == ""} {
     putserv "PRIVMSG $nick :Usage: TOPIC <channel>"
     return 0
  }

  if {[lsearch -exact [string tolower [channels]] [string tolower $channel]] == -1} {
     putserv "PRIVMSG $nick : «»  I am not on ${channel}.  «» "
     return 0
  }

  putserv "PRIVMSG $nick : «»  Topics for $channel:  "

  set ctr 0
  if {[info exists random_topic([string tolower $channel])]} {
    foreach i $random_topic([string tolower $channel]) {
       incr ctr 1
       putserv "PRIVMSG $nick :${ctr}.  $i"
    }
  } {
    putserv "PRIVMSG $nick :  «»  No topics set.  «» "
  }
  putserv "PRIVMSG $nick : «»  end of topics list  «» "
  if {$hand != "*" && [matchattr $hand m]} {
     putserv "PRIVMSG $nick : «» To add a topic type /msg $botnick TOPIC HELP for help.  «» "
  }

  return 1
}

proc topic_add {nick uhost hand arg} {
  global random_topic topics_changed

  if {![matchattr $hand m]} {
     putserv "PRIVMSG $nick :Sorry, you are not authorized to use this command."
     return 0
  }

  set channel [lindex $arg 1]

  if {$channel == ""} {
     putserv "PRIVMSG $nick :Usage: TOPIC ADD <channel> <new topic>"
     return 0
  }

  if {[lsearch -exact [string tolower [channels]] [string tolower $channel]] == -1} {
     putserv "PRIVMSG $nick : «» I am not on ${channel}. «» "
     return 0
  }

  putserv "PRIVMSG $nick :Topic list has been updated, thanks."
  putserv "PRIVMSG $nick :[lrange $arg 1 end]"
  lappend random_topic([string tolower $channel]) [lrange $arg 2 end]
  set topics_changed 1

  return 1
}

proc topic_erase {nick uhost hand arg} {
  global random_topic topics_changed

  if {![matchattr $hand m]} {
     putserv "PRIVMSG $nick :Sorry, you are not authorized to use this command."
     return 0
  }

  set channel [lindex $arg 1]
  if {$channel == ""} {
     putserv "PRIVMSG $nick :Usage: TOPIC DEL <channel> <topic#>"
     return 0
  }

  if {[lsearch -exact [string tolower [channels]] [string tolower $channel]] == -1} {
     putserv "PRIVMSG $nick : «» I am not on ${channel}. «» "
     return 0
  }

  if {![info exists random_topic([string tolower $channel])]} {
     putserv "PRIVMSG $nick : «» No topics set. «» "
     return 0
  }

  set i [expr [lindex $arg 2] - 1]
  if {$i >=0 && [lindex $random_topic([string tolower $channel]) $i] != ""} {
     putserv "PRIVMSG $nick :Entry [lindex $arg 2] erased."
     putserv "PRIVMSG $nick :$channel [lindex $random_topic([string tolower $channel]) $i]"
     set random_topic([string tolower $channel]) [lreplace $random_topic([string tolower $channel]) $i $i]
     set topics_changed 1
     return 1
  } {
     putserv "PRIVMSG $nick : «» That number is out of range! «» "
     return 0
  }
}

proc topic_set {nick uhost hand arg} {
  global random_topic

  if {![matchattr $hand m]} {
     putserv "PRIVMSG $nick : «» Sorry, you are not authorized to use this command. «» "
     return 0
  }

  set channel [lindex $arg 1]
  if {$channel == ""} {
     putserv "PRIVMSG $nick :Usage: TOPIC SET <channel> <topic#>"
     return 0
  }

  if {[lsearch -exact [string tolower [channels]] [string tolower $channel]] == -1} {
     putserv "PRIVMSG $nick : «» I am not on ${channel}. «» "
     return 0
  }

  if {![info exists random_topic([string tolower $channel])]} {
     putserv "PRIVMSG $nick :No topics set."
     return 0
  }

  set i [expr [lindex $arg 2] - 1]
  if {$i >=0 && [lindex $random_topic([string tolower $channel]) $i] != ""} {
     putserv "PRIVMSG $nick :Setting current topic to entry [lindex $arg 2]."
     putserv "TOPIC $channel :[lindex $random_topic([string tolower $channel]) $i]"
     return 1
  } {
     putserv "PRIVMSG $nick :That number is out of range!"
     return 0
  }
}

proc topic_refresh {nick uhost hand arg} {
   global topic_refresh_rate

  if {![matchattr $hand m]} {
     putserv "PRIVMSG $nick :Sorry, you are not authorized to use this command."
     return 0
  }

  if {[lindex $arg 1] == ""} {
     putserv "PRIVMSG $nick :Usage: TOPIC REF <minutes>"
     return 0
  }

  set i [lindex $arg 1]
  if {$i < 30 || $i > 240} {
     putserv "PRIVMSG $nick :Refresh rate range is 30 - 240 minutes."
     return 0
  } {
     set topic_refresh_rate $i
     putserv "PRIVMSG $nick :Refresh rate has been changed to $topic_refresh_rate minutes, this change"
     putserv "PRIVMSG $nick :will be effective after the next topic change."
     return 1
  }
}

proc topic_help {nick uhost hand arg} {
  putserv "PRIVMSG $nick :Usage: TOPIC                  - show topics"
  if {[matchattr $hand m]} {
    putserv "PRIVMSG $nick : «»    TOPIC ADD <channel> <new topic>  - add topic entry"
    putserv "PRIVMSG $nick : «»    TOPIC DEL <channel> <topic#>     - delete topic entry"
    putserv "PRIVMSG $nick : «»    TOPIC SET <channel> <topic#>     - set current topic to topic#"
    putserv "PRIVMSG $nick : «»    TOPIC REF <minutes>              - change topic refresh rate"
  }

  return 1
}

proc topic_load {} {
   global random_topic topicfile

   if {[info exists random_topic]} {unset random_topic}
   if {[catch {set fd [open $topicfile r]}] != 0} {return 0}
   while {![eof $fd]} {
      set inp [gets $fd]
      if {[eof $fd]} {break}
      if {[string trim $inp " "] == ""} {continue}
      set channel [lindex $inp 0]
      lappend random_topic([string tolower $channel]) [lrange $inp 1 end]
   }
   close $fd

   return 1
}

proc topic_write {} {
   global topicfile random_topic topics_changed

   set fd [open $topicfile w]
   foreach channel [array names random_topic] {
      if {[lsearch -exact [string tolower [channels]] [string tolower $channel]] != -1} {
         foreach i $random_topic([string tolower $channel]) {
            puts $fd "$channel $i"
         }
      }
   }
   close $fd

   set topics_changed 0
   return 1
}


proc msg_topic {nick uhost hand arg} {
  switch [string tolower [lindex $arg 0]] {
    "add"       {set r [topic_add $nick $uhost $hand $arg]}
    "del"	{set r [topic_erase $nick $uhost $hand $arg]}
    "delete"	{set r [topic_erase $nick $uhost $hand $arg]}
    "set"	{set r [topic_set $nick $uhost $hand $arg]}
    "ref"	{set r [topic_refresh $nick $uhost $hand $arg]}
    "refresh"	{set r [topic_refresh $nick $uhost $hand $arg]}
    "help"	{set r [topic_help $nick $uhost $hand $arg]}
    default     {set r [topic_show $nick $uhost $hand $arg]}
  }
  return $r
}

if {![info exists set_topic_running] && ![info exists random_topic]} {
  sync_topic
  set set_topic_running 1
}


set topics_changed 0

### End of topic 
#### Console TCL  ######
# ok, so there are basically two ways you can do this:
# 1) console mode is automatically saved when you leave
#    advantages: automatic -- any console mode changes you do will stick
#    disadvantages: if you're on the bot twice, whichever session exits
#       last will be the one to get saved
# 2) console mode is saved by typing '.store'
#    advantages: can set console the way you like it, store it that way,
#       and then make temporary changes later as you like
#    disadvantages: won't save changes if you forget to use '.store'
#

# set which mode you want here:
# (0 = use '.store')  (1 = automatic save when you leave)
set console-autosave 1


##########################################################################

if {![info exists toolkit_loaded]} {
  catch {source scripts/toolkit.tcl}
  if {![info exists toolkit_loaded]} {
    catch {source toolkit.tcl}
    if {![info exists toolkit_loaded]} {
      error "Can't load Tcl toolkit!"
    }
  }
}

if {${console-autosave}} {
  bind chof - * save_console
} {
  bind dcc - store save_console_dcc
}
bind chon - * restore_console

proc restore_console {handle idx} {
  set cons [user-get $handle console]
  set conchan [user-get $handle conchan]
  if {$cons != ""} {
    if {$conchan != ""} {
      console $idx $conchan $cons
    } {
      console $idx $cons
    }
  }
  set echo [user-get $handle echo]
  if {$echo != ""} { echo $idx $echo }
}

proc save_console {handle idx} {
  set cons [console $idx]
  user-set $handle conchan [lindex $cons 0]
  user-set $handle console [lindex $cons 1]
  user-set $handle echo [echo $idx]
}
proc save_console_dcc {handle idx param} {
  set cons [console $idx]
  user-set $handle conchan [lindex $cons 0]
  user-set $handle console [lindex $cons 1]
  user-set $handle echo [echo $idx]
  set newcons "[lindex $cons 0]: [lindex $cons 1]"
  if {[echo $idx]} {
    putdcc $idx "Saved your console mode as $newcons (echo on)"
  } {   
    putdcc $idx "Saved your console mode as $newcons (echo off)"
  }
  return 1
}
###End of Console.TCL ####################

set_bot_away

timer 3 set_bot_away

loadchans

putlog " «»      "
putlog " «» Checking For X-TreMe Topics (Found and loaded)" 
topic_load