egghelp.org community Forum Index
[ egghelp.org home | forum home ]
egghelp.org community
Discussion of eggdrop bots, shell accounts and tcl scripts.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[SOLVED] How to Call a Single Variable with Multiple Values

 
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help
View previous topic :: View next topic  
Author Message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Wed Apr 20, 2011 1:21 pm    Post subject: [SOLVED] How to Call a Single Variable with Multiple Values Reply with quote

So, here's my question. If I have a single variable set with multiple values, as sampled below:

Code:
set triggerwords {
mess
messy
mop
shift
crate
lamp
ocean
sea
}


And I want to use the variable $triggerwords to kick off a proc. Will the following code work properly if only one of the values is use in a line of text?

Code:
bind pub - $triggerwords randaction

proc randaction {nick uhost channel hand text} {
putserv "PRIVMSG $channel :\001ACTION $randline."
}


$randline is a variable from another piece of code. I think you can see what I'm going for, with the format.

I keep re-reading it and thinking there's something wrong or missing.


Last edited by Seka on Thu Apr 21, 2011 2:33 pm; edited 1 time in total
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Wed Apr 20, 2011 2:05 pm    Post subject: Reply with quote

Technically, triggerwords has a single value. It's just a long string with multiple newlines within it. To some extent, it could also be considered a handcrafted list (though this requires caution).

The "pub" binds, or triggers, are matched against individual lines of text from a channel (and only against the first word of the line), so having multiple words or lines will not provide a suitable mask. However, there is nothing preventing you from creating multiple triggers; one for each word of your crafted list.
Something like this should take care of that:
Code:
...
foreach item $triggerwords {
  bind pub - $item randaction
}
...


Now, for your proc "randaction";
You try to read the local variable randline, though there exists no such local variable within the proc. I would guess you intended to access the globalspace variable randline instead:
Code:
proc randaction {nick host handle channel text} {
  puthelp "PRIVMSG $channel :\001ACTION $::randline\001"
}

This uses the :: fully qualified namespace path to access the variable. You could also use the "global" command to link the localspace variable to the globalspace of the same name though.
I also fixed the order of your parameters to match what the trigger will provide when calling the proc.
_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Wed Apr 20, 2011 2:20 pm    Post subject: Reply with quote

Awesome.

I will put this together and give it a try when I get back home.

Thanks for the help!
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Tue Apr 26, 2011 1:21 pm    Post subject: Reply with quote

The script is working the way it should, but I have one more issue.

The proc only responds when the trigger word is the first word in the post. So, it won't kick off if the word is in an "action" post or if the word is within a statement.

i.e. If the trigger word is "ocean" and a user says:

"The ocean is blue today!"
or
/me looks at the ocean.

Neither of the above posts will trigger the proc.

Any suggestions?
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Tue Apr 26, 2011 1:43 pm    Post subject: Reply with quote

For actions, you have to remember that they're simple CTCP-action commands. As such, you'll need to use the CTCP binding for those. However, reading the docs, you'll see that the ctcp-bindings only matches against the ctcp-command, not it's arguments.. thus you'll have to bind against ACTION, and do some additional checking within your code:
Code:
...
if {[string match -nocase -- "*ocean*" $the_text]} {
  #Stuff to do if the action contains "ocean"


Next, for normal messages, this is a little simpler; you'll have to replace the pub binding with a pubm (matching binding), along with a proper mask. Something like this should do the trick:
Code:
bind pubm - "% *ocean*" pubm::randaction


Needless to say, since we're changing the bindings, make sure you adapt your proc(s) to the new bindings. Also, don't use the same proc for multiple bindings of different kinds unless you are absolutely sure on what you're doing - generally, it's a better idea to create a separate proc for each kind of binding.
_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Tue Apr 26, 2011 1:47 pm    Post subject: Reply with quote

Instead of using "*ocean*" since I stored the trigger words in $item, can I use that variable in the statement? Like below:

Code:
bind pubm - $item pubm::randaction


Or will that rip a whole in the universe?

I can see that getting this script to do what I want is going to be a lot more effort than I'd planned for.
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Tue Apr 26, 2011 2:21 pm    Post subject: Reply with quote

You could use $item to replace the ocean part of the mask (assuming that the variable exists in the given context).
The mask has to match against "#channel text spoken", so at a minimum you'd have to use "% *${item}*" or "*${item}*" (the latter would also match if the "trigger-word" is present in the channel name, which is why I recommend the first one).
_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Tue Apr 26, 2011 2:33 pm    Post subject: Reply with quote

Ok. Here is what I have for both of my binds and procs. They're also both present in the same script. I'm not sure if that is going to cause a problem, in itself.

I apologize for the lack of formatting. My editor doesn't appreciate TCL.

Code:
foreach item $triggerwords {
 bind pubm - "% *${item}*" pubm:randaction
}

proc pubm:randaction {nick host hand channel text} {
putserv "PRIVMSG $channel ":\001ACTION $randline \001"
}


I omitted the lines that generate the $randline variable, for the sake of space.

Here is the ctcp bind:

Code:
bind ctcp - "ACTION" action_randaction

proc action_randaction {nick host hand dest keyword text} {
if {[string index $dest 0] !="#"} {return 0} then {
 if {[string match -nocase -- "*$::item*" $text]} {
  putserv "PRIVMSG $channel :\001ACTION $randline \001"
  }
 }
}


Same deal here. The code for $randline does exist in the script. It's just missing here for the sake of space.
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Tue Apr 26, 2011 2:40 pm    Post subject: Reply with quote

The first part looks ok.

As for the second part, your if-conditional is not proper; you can't have the "then" keyword in it's current position. The proper syntax is as follows:
Code:
if {test} then {true-code} else {false-code}

#To ease readability, newlines may be added like this:
if {test} then {
  true-code
} else {
  false-code
}

#Further, the "then" and "else" keywords are optional:
if {test} {
  true-code
} {
  false-code
}

#Finally, we could also leave out the false-code part if it's not needed:
if {test} {
  true-code
}

In the above code, "test" would be a test that returns true or false;
true-code is a block of tcl-code that is to be evaluated if the test returns true;
false-code is a block of tcl-code that is to be evaluated if the test returns false
_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Tue Apr 26, 2011 2:45 pm    Post subject: Reply with quote

Ah, I see.

I dropped the "then" from the statement. The part that concerns me is the string match:

Code:
if {[string match -nocase -- "*$::item*" $text]} {


Is the variable formatted properly to generate a positive match? "*$::item*" seems so convoluted.
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Tue Apr 26, 2011 2:48 pm    Post subject: Reply with quote

Oh, overlooked that part..
In this case, $::item would only hold the value of the last item of $triggerwords. You would have to use a similar foreach-loop within the proc to test each item in the list. You would also have to use break or return to prevent multiple responses if one line contains several of the triggers.
_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
Seka
Voice


Joined: 19 Apr 2011
Posts: 18

PostPosted: Tue Apr 26, 2011 2:56 pm    Post subject: Reply with quote

That piece may be a little beyond my means, then.

I really do appreciate all of the help you've given me with all of my requests! If there was a way to bump your ID to "guru" status, I would cast my vote! Smile

Thank you again, for all of your help and patience. I've learned a lot about TCL.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    egghelp.org community Forum Index -> Scripting Help All times are GMT - 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Forum hosting provided by Reverse.net

Powered by phpBB © 2001, 2005 phpBB Group
subGreen style by ktauber