This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

First try using namespace

Help for those learning Tcl or writing their own scripts.
Post Reply
User avatar
et109
Voice
Posts: 7
Joined: Sun Feb 25, 2007 9:47 am
Location: Pennsylavnia

First try using namespace

Post by et109 »

This is my first attempt at using namespaces, and I would really appreciate any comments or advice. (especially with the timer stuff)
TIA

Code: Select all

###############################################################################################
#namespace Solobot
#Checks for availability of bot's user's (on bot userlist with with appropriate channel flags
#set) in IRC channels
#scans channels for user availability using "WHOIS" command, adds '+A' flag to user attr if away
#If all users in chan's list are away, bot is solo in channel and adds '+S' flag to channel
#If channel is +S bot is to explain no live help currently available and  offer limited help to
#guests joining channel i.e. access to bot's #help files, links to help sites etc.
# TODO add binds and handlers for channel join events
################################################################################################

#system setup for namespace

bind dcc - "startsolo" Solobot::Execute
bind dcc - "stopsolo" Solobot::Stop
bind dcc - "nosolo" Solobot::Destroy

bind raw - "301" Solobot::Whoisreply
bind raw - "318" Solobot::Whoisreply

setudef flag A
setudef flag S


namespace eval Solobot {

    namespace export Execute Stop Destroy
 
    variable bypass 0
    variable timerid
    variable firstpass 1

    #####################################################################################
    #scan channels list 
    #check for available users in each channel
    #set timer to rescan 
    #####################################################################################
    proc Execute {args} {
      variable firstpass
      variable timerid
      #first pass through channels
      if {$firstpass} {
          variable firstpass 0
          foreach chan [::channels] {
           putlog "$::botnick beginning watch $chan [strftime "\[%H:%M:%S\]\(%a.\)%D"]"
          }
      }
      #scan channels
      foreach chan [::channels] {
         putlog "$chan"
         #scan channel user list
         foreach user [::chanlist $chan n|m|l ] {
           putquick "Whois $user"
         }
         #check for availability
         Chkaides $chan
      }
      #kill timer if it exists
      if { [set timr [timerexists timerid]] != "" } {
    	      putlog "$timerid killed"
              killutimer $timerid
      }
      # set new timer to rescan
      set timerid [utimer 20 Solobot::Execute]
      return 0 
    } 
    
    #####################################################################################
    #stop channel scan
    #####################################################################################
    proc Stop {args} {
       variable timerid
       #kill timer if it exists
       if { [set timr [timerexists timerid]] != "" } {
    	      putlog "$timerid killed"
              killutimer $timerid
       }
       killutimer $timerid
       #notify operator that scanning has stopped
       putlog "$::botnick ending watch for all channels [strftime "\[%H:%M:%S\]\(%a.\)%D"]"
    
    }
    #####################################################################################
    #Remove namespace
    #####################################################################################
    proc Destroy {args} {
       Stop
       putlog "removing Solobot"
       unbind dcc - "startsolo" Solobot::Execute
       unbind dcc - "stopsolo" Solobot::Stop
       unbind dcc - "nosolo" Solobot::Destroy
       unbind raw - "301" Solobot::Whoisreply
       unbind raw - "318" Solobot::Whoisreply
       deludef flag A
       deludef flag S
       namespace delete ::Solobot 
    
    }
    
    #####################################################################################
    #process whois replies
    #####################################################################################
    proc Whoisreply {serv raw text} {
        variable bypass
        #parse reply
        set tmp [split $text : ]
        set tmp1 [split [lindex $tmp 0] ]
        set aide [lindex $tmp1 1]
        #if user away (301) set user 'A' flag and 
	#set bypass flag to catch trailing code 318
        #then return
        if { $raw eq "301" } {
            set bucket [chattr $aide +A]
            set bypass 1
            return 0 
           #catch trailing code 318, unset bypass flag
           #then return                     
         } elseif {$bypass == 1} {
                  set bypass 0
                  return 0
                 #318 flag only (no leading 301) - indicates user is not away
                 #unset 'A' flag and return                     
                 } else { 
                         set bucket [chattr $aide -A]
                         return 0                     
                        }
    
    }
    
    #####################################################################################
    #check for bots 'solo' status
    #####################################################################################
    proc Chkaides {chan} {
         set users 0
         set away 0
         #count users on chan list with appropriate flags
         foreach user [::chanlist $chan m|n|l ] {
              incr users
              #if the user is also flagged away add them to user away count
              if {[regexp -- {A} [chattr $user] ]} {
                    incr away
                 }
         }
         #if all the users are 'away' set the chan +S 
         if { $users == $away } {
               channel set $chan +S
               putlog "$::botnick solo in $chan"
             } else {
                      #if any users not flagged 'away' set channel -S
                      channel set $chan -S
                      putlog "$::botnick has help in $chan"
                   } 
    
    }

  #########################################################################################
  ###########################         end namespace         ###############################
  #########################################################################################
}



O
Ofloo
Owner
Posts: 953
Joined: Tue May 13, 2003 1:37 am
Location: Belguim
Contact:

Post by Ofloo »

I would put the binds on the end of the script within the namespace and use

bind <type> <flag> <cmd> [namespace current]::myproc
XplaiN but think of me as stupid
User avatar
et109
Voice
Posts: 7
Joined: Sun Feb 25, 2007 9:47 am
Location: Pennsylavnia

binds innamespace at bottom

Post by et109 »

should I put the flag defs inside the namespace also?

Also I just added binds for the join event in my copy here.
I put them in the "firstpass" section of the Solobot::Execute proc
does this look copacetic?

Code: Select all

      #first pass through channels
      if {$firstpass} {
          variable firstpass 0
          foreach chan [::channels] {
            putlog "$::botnick beginning watch $chan [strftime "\[%H:%M:%S\]\(%a.\)%D"]"
            #bind joins to channels on bots channel list
            bind join - $chan Solobot::Chkjoin 
          }
      }
User avatar
Sir_Fz
Revered One
Posts: 3794
Joined: Sun Apr 27, 2003 3:10 pm
Location: Lebanon
Contact:

Post by Sir_Fz »

You don't have to use [::channels] or [::chanlist], you can use simply [channels] and [chanlist] since these proc names are not overridden in your namespace.

Also:
JOIN (stackable)
bind join <flags> <mask> <proc>
procname <nick> <user@host> <handle> <channel>

Description: triggered by someone joining the channel. The mask in
the bind is matched against "#channel nick!user@host" and can
contain wildcards.
Try your code, don't ask here unless you have a specific problem that you need help with.
User avatar
et109
Voice
Posts: 7
Joined: Sun Feb 25, 2007 9:47 am
Location: Pennsylavnia

Specific problems

Post by et109 »

In truth I did have 2 specific problems with the code.
You either saw the bind problem or sensed it. A careful reading of the quote you posted
brought me the solution to it. I had not included a host mask in the bind.
The second problem was with the timer, or rather the finding and killing of it.
The egghelp forum thread: Posted: Wed Jun 22, 2005 7:54 pm Post subject: Searching and killing timers
gave me the solution to that.
Thank you for your help
Post Reply