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.

Help with tcl script

Help for those learning Tcl or writing their own scripts.
[
[3-33]
Voice
Posts: 6
Joined: Sat Aug 08, 2009 6:18 am

Help with tcl script

Post by [3-33] »

First, if i open this topic in wrong place, sorry, because its my first posting on this forum.

I have a problem,with my eggdrop. I am using a tcl script called "bottalk".The preformance of this script is that, when the bot is talked, by he`s nick name, should respond to the user. There is a few options, like this:

Code: Select all

bind pub - "$nick:" pub_dotalkz
bind pub - "$nick" pub_dotalkz
bind pub - "$nick," pub_dotalkz
bind pub - "$nick;" pub_dotalkz
but the problem is that,it works with all commands like bottnick, bottnick: bottnick; , but it doesnt work when just the NICKNAME of the bot is talked.
(Loock at the second code - "$nick") Can, someone help me to solve this problem?
The end is a new begining
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

I don't see anything wrong with the bind statement. Certainly if the three with punctuation characters work, then the one without should be fine PROVIDING the first word of the channel text is the bot's primary nick followed by a space.

I would point out that the bot's current nick (as returned by $botnick) may be different than the bot's primary nick (as set in the .conf file and returned by $nick). If it so happened that the bot was using an alternative nick (maybe its primary nick was in use) at the time you tested the second bind, then the bind would not trigger if you used the bot's current nick ($botnick) as the first word of the channel text (the command for a PUB bind).

I think I would be tempted to change them all from $nick to $botnick. I think I would probably also do something to stress that any punctuation is not a part of the variable name, even though they did work without modification.

bind PUB - $botnick pub_dotalkz
bind PUB - ${botnick}; pub_dotalkz
bind PUB - ${botnick}: pub_dotalkz
bind PUB - ${botnick}, pub_dotalkz
I must have had nothing to do
[
[3-33]
Voice
Posts: 6
Joined: Sat Aug 08, 2009 6:18 am

Post by [3-33] »

Tnx for trying to help me , but it still doesnt work, i try ur advice, also i`v try this version:

Code: Select all

bind pub - "$nick:" pub_dotalkz 
bind pub - "$botnick"  pub_dotalkz 
bind pub - "$nick," pub_dotalkz 
bind pub - "$nick;" pub_dotalkz
but it doesnt work. What can be the problem? In the tcl can not be the problem because i`v just download the tcl-script, that meens there is no place for mistakes maded by me:)

Does it meens what eggdrop i have or?
The end is a new begining
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

The problem must be elsewhere in the script you have downloaded. In order to test, I made the following very simple script.

Code: Select all

bind PUB - $botnick pub_dotalkz

proc pub_dotalkz {nick uhost hand chan text} {
    putserv "PRIVMSG $chan :$nick, what do you want"
    return 0
}
This is the channel output :-

[15:11] <@arfer> osmosis hello
[15:11] <@osmosis> arfer, what do you want
[15:11] <@arfer> Osmosis hello
[15:11] <@osmosis> arfer, what do you want
I must have had nothing to do
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

One thing you have to keep in mind, is that using $botnick will not alter the binding as the nickname changes. In fact, I'm not sure $botnick would contain anything but the empty string ("") during startup, as your bot would not yet have established a connection to any irc servers yet.

If you'd like it to respond to the "current" nickname, regardless of what nicknames was used earlier, you'd have to use the pubm binding with a match-all mask (*), and then within the triggered proc test the spoken text against $::botnick.

As for why appending a , to the nickname won't work, I'll have to dig further into the code to check that...
NML_375
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

Yes thats a good point. It is probably why the author chose $nick rather than $botnick in the first place. If I was coding this, there is no doubt I would have done as you suggested and used a PUBM bind.
I must have had nothing to do
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

Code: Select all

variable nickchars " :,;"

bind pubm - * pub_shouldwetalk

proc pub_shouldwetalk {nick uhost hand chan text} {
   foreach entry $::nickchars {
      set test [list "${::botnick}${entry}"]
      if {[string match "[lindex $test 0]*" $text]} {
         regsub "[lindex $test 0]" $text "" output
         pub_dotalkz $nick $uhost $hand $chan $output
      }
   }
}
Something like this should work, and would just act as a "stub" to detect should the bot talk and if so passes execution along to the normal procedure pub_dotalkz. This is the easiest way to accomplish it.
  • and [lindex] is used to avoid possible conflicts with special tcl characters during the regsub with evaluated variable contents.
Last edited by speechles on Sat Aug 08, 2009 1:21 pm, edited 1 time in total.
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

speechles,
wouldn't it be better to use ${::botnick} than ${::nick}?

Also, mind if I ask why you create $test as a single-item list, as you only access it using "lindex $test 0" all throughout the script anyway?
NML_375
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

nml375 wrote:speechles,
wouldn't it be better to use ${::botnick} than ${::nick}?

Also, mind if I ask why you create $test as a single-item list, as you only access it using "lindex $test 0" all throughout the script anyway?
Yep, your 100% correct. $::botnick will cover both $::nick/$::altnick. Meaning using just $::nick will NOT cover when the bot is using it's alternate nickname, but $::botnick will.

And about the
  • /[lindex] it's because of the [regsub] used to remove the botnick and char used to seperate it from the text. This could cause double evaluation and if the bot's nickname has special characters like [die] the bot may just decide to die. List is a cheap way to escape any potential issues. This is just a precaution I'm not even sure is needed.
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

There's no risk of double evaluation with regsub, the exp argument will never be passed to a second interpreter. A common practise with any regular expression (in tcl), is to encapsulate them with {} rather than "", since they specifically make use of [] as an integral part (same would apply to some glob-style pattern/matching as well, although it's not as common).

However, doing something like this:

Code: Select all

set tmp [list content]
utimer 1 [lindex $tmp 0]
does not protect against double evaluation, as this would be identical to this:

Code: Select all

set tmp content
utimer 1 $tmp
##or simply:
utimer 1 content
NML_375
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

This should work. A little simpler.

Code: Select all

bind PUBM - * pubm_checktalkz

proc pubm_checktalkz {nick uhost hand chan text} {
    global botnick
    if {[regexp -nocase -- [subst -nocommands {^$botnick[,;:]?}] $text]} {
        set output [join [lrange [split $text] 1 end]]
        pub_dotalkz $nick $uhost $hand $chan $output
    }
    return 0
}
I must have had nothing to do
[
[3-33]
Voice
Posts: 6
Joined: Sat Aug 08, 2009 6:18 am

Post by [3-33] »

arfer wrote:The problem must be elsewhere in the script you have downloaded. In order to test, I made the following very simple script.

Code: Select all

bind PUB - $botnick pub_dotalkz

proc pub_dotalkz {nick uhost hand chan text} {
    putserv "PRIVMSG $chan :$nick, what do you want"
    return 0
}
This is the channel output :-

[15:11] <@arfer> osmosis hello
[15:11] <@osmosis> arfer, what do you want
[15:11] <@arfer> Osmosis hello
[15:11] <@osmosis> arfer, what do you want
I`v test this and it wasnt work:)

Maybe its something with my eggdrop ...

anyway this script i am using:

Code: Select all

http://www.egghelp.org/cgi-bin/tcl_archive.tcl?mode=download&id=853
The end is a new begining
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

I'm sorry [3-33] but if you have been reading this thread, then you would know that using $botnick in a bind (which executes before the bot comes online) will probably not work. I was wrong.

My little test script was manually loaded via a partyline tcl command AFTER the bot was online.

However, it would be fair to say that none of us have managed to address your problem. We cannot see from what you have posted why $nick, $nick; and $nick: should work but not $nick alone. I doubt that it is your eggdrop, though it could be something in the script that we are unaware of.
I must have had nothing to do
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

arfer wrote:However, it would be fair to say that none of us have managed to address your problem. We cannot see from what you have posted why $nick, $nick; and $nick: should work but not $nick alone. I doubt that it is your eggdrop, though it could be something in the script that we are unaware of.
procedure found while searching google wrote:

Code: Select all

proc pub_dotalkz {nick uhost hand chan rest} {
  global botnick
  global TalkzStrArray
  global TalkzChanArray
  global ignore_words
  global bad_nicks

  set str [lrange $rest 0 end]

  if {[lsearch [join $TalkzChanArray] $chan] == -1} { return 0 }
  
  if {$nick == $botnick} {
    return 0
  }

  if {$str == ""} {
    putchan $chan "$nick: euh ... quoi ?"
    return 0
  }

  foreach i $bad_nicks {
   if {[string match [string tolower $nick] [string tolower $i]]} {
     return 0
   }
  }

  foreach i $ignore_words {
    foreach j [join $rest] {
      if {[string match [string tolower $j] [string tolower $i]]} {
        return 0
      }
    }
  }
 
  set nrword [rand [llength $str]]
  set nword [lrange $str $nrword $nrword]

  set ntalk [lsearch -regexp $TalkzStrArray ".*[FixStrReg $nword].*"]

  set n [rand 100]
  set m [rand 400]
  
  # si le nom du bot est dans la phrase, on r�pond en indiquant le nom de la personne
  # qui nous parle
  set tt [lsearch -regexp $str ".*$botnick.*"]
  if {$tt != -1} {
   if { ($ntalk > 0) && ([rand 10] > 5) } {
    set dit [lindex $TalkzStrArray $ntalk]
    while {[lsearch -regexp $dit ".*$botnick.*"] != -1} {
      regsub -all "$botnick" $dit "[lindex [chanlist $chan] [rand [llength [chanlist $chan]]]]" dit
    }
    putchan $chan "$nick: $dit"
   } else {
    set dit [lindex $TalkzStrArray [expr [rand [llength $TalkzStrArray]]]]
    while {[lsearch -regexp $dit ".*$botnick.*"] != -1} {
      regsub -all "$botnick" $dit "[lindex [chanlist $chan] [rand [llength [chanlist $chan]]]]" dit
    }
    putchan $chan "$nick: $dit"
   }
  # sinon on dit une phrase quelque fois, juste comme �a
  } else {
   if {$n > $m} {
    set dit [lindex $TalkzStrArray [expr [rand [llength $TalkzStrArray]]]]
    while {[lsearch -regexp $dit ".*$botnick.*"] != -1} {
      regsub -all "$botnick" $dit "[lindex [chanlist $chan] [rand [llength [chanlist $chan]]]]" dit
    }
    putchan $chan "$dit"
   }
  }
  set qui [string trimright [lindex $str 0] :]
  if {($qui != $botnick) && ([onchan $qui $chan])} {
    set str [lrange $str 1 end]
    if {[lindex $str 0] == ":"} { set str [lrange 1 end] }
    lappend TalkzStrArray [FixStr $str]
  } else {
    lappend TalkzStrArray [FixStr $str]
  }
}
This should now shed some light on what is going on. ;)
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

I downloaded bottalk.tcl from this site. After loading the script and restarting I was able to get my bot to respond to $nick, $nick; $nick: AND $nick alone.

[22:41] <@arfer> Osmosis
[22:41] <@osmosis> arfer: What? ×åãî íàäî ?
[22:41] <@arfer> osmosis
[22:41] <@osmosis> arfer: What? ×åãî íàäî ?
[22:42] <@arfer> osmosis, hello
[22:42] <@osmosis> arfer: Ïèâî åñòü ?
[22:42] <@arfer> Osmosis: hello
[22:42] <@osmosis> arfer: Ñêîê ãîäèêîâ òåáå ?
[22:42] <@arfer> Osmosis; what are you doing?
[22:42] <@osmosis> arfer: hello

I don't have a clue what the original poster did to break it.
I must have had nothing to do
Post Reply