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.

need help with lists

Help for those learning Tcl or writing their own scripts.
Post Reply
a
alkoleht
Voice
Posts: 6
Joined: Sun Jun 26, 2011 8:12 am

need help with lists

Post by alkoleht »

Hi. I am pretty noob when it comes to TCL but i am trying to learn.
I am trying to create a script that will take user msg to bot, does some matching and relays it to chan.
here is how it looks in reality:

1. let's say i have a list of words:

Code: Select all

set word {
flower
bee
house
}
2. user MSG-s to bot, ether just one word or more text, doesnt matter.
example:

Code: Select all

/msg bot house is tv show
3. script then takes the first word of imput and matches that to $word . also no matter if the input is CAPS or lower case or MiXeD
4. if first word matches then say in chan:

Code: Select all

<bot> $nick sayd $word
if the first word does not match $word list then it will say the full imput into the chan.

so example:

Code: Select all

<user>/msg <bot> house is tv show
<bot> <user> says word [b]house[/b]

<user>/msg <bot> there is a house in tv right now
<bot> <user> says: there is a house in tv right now
i know it may sound strange but that is something i want to create.
any help with this would be appreciated
Thank you
User avatar
Madalin
Master
Posts: 310
Joined: Fri Jun 24, 2005 11:36 am
Location: Constanta, Romania
Contact:

Post by Madalin »

Try this code and tell if this is what you wanted

Code: Select all

bind MSGM - * check:msgm

set temp(chan) "#channel"
set temp(words) {
	"word1"
	"word2"
}

proc check:msgm {nick uhost hand arg} {
	global temp

	foreach a $temp(words) {
		if {[string match -nocase $a [lindex [split $arg] 0]]} {
			putserv "PRIVMSG $temp(chan) :$nick said \002[lindex [split $arg] 0]\002"
			return
		} else {
			putserv "PRIVMSG $temp(chan) :$nick said: $arg"
			return
		}
	}
}
a
alkoleht
Voice
Posts: 6
Joined: Sun Jun 26, 2011 8:12 am

Post by alkoleht »

awesome, it works. thank you.
i was going completely different approach to this problem before but this solution works just perfect. Much appreciated
User avatar
Madalin
Master
Posts: 310
Joined: Fri Jun 24, 2005 11:36 am
Location: Constanta, Romania
Contact:

Post by Madalin »

No problem, glad i could help
L
LoKii
Voice
Posts: 34
Joined: Wed Oct 21, 2009 3:59 am

Post by LoKii »

forgive me for hijacking this thread, a small question regarding it.

This code is based on the first word said in the sentence, but if i want to capture any word from the sentence which is in the temp(words) list, how would i go about doing it, if the word is NOT the first word?

Cheers.
User avatar
Papillon
Owner
Posts: 724
Joined: Fri Feb 15, 2002 8:00 pm
Location: *.no

Post by Papillon »

Madalin:
Instead of using a foreach loop which is slow, why not just use the standard tcl-command lsearch?

LoKii:
In that case I would use a loop on each word said by the user and do a lsearch on the list. Word of warning though, if your channel is very crowded and people are chatty this will be very time-consuming on the bot. I have not been writing tcl-code for years and have forgotten alot, so might be a much more effecient way of doing it if you search around :)
Elen sila lúmenn' omentielvo
User avatar
Madalin
Master
Posts: 310
Joined: Fri Jun 24, 2005 11:36 am
Location: Constanta, Romania
Contact:

Post by Madalin »

I am trying more and more to use lsearch (i never used that in the past) so i have to try use it now in the present :) yet as i used foreach alot it would be a little weird for me at start :) but ill try use it.
L
LoKii
Voice
Posts: 34
Joined: Wed Oct 21, 2009 3:59 am

Post by LoKii »

Yes, i also discovered that lsearch is the way to go.

What i am trying to accomplish is, i took a script called: forward.tcl written by r0gUe.

His script basicly just relays any msg to the bot to a specified channel.

What i want to do, is to edit it, so that certain messages are not relayed with the same output, due to security, such as pass/ident/auth/addhost etc....

What i have so far is:

Code: Select all

bind msgm - "*" proc_msgm
proc proc_msgm {nick uhost hand arg} {
    set chan "#prototype"
    set line [string trim $arg]
    set temp {
        "verify"
        "ident"
        "addhost"
        "pass"
    }
    foreach a $temp [split $arg]{
        if {[string match -nocase $a $arg]} {
            putserv "PRIVMSG $chan :$nick has used the $a command"
            
        }
    }
    puthelp "PRIVMSG $chan :$nick messaged me saying: '$line'"
    return 1
}
So I am not too worried about large rooms and such, since its only in the rare cases that someone pms the bot. I just want to make sure that no passwords though go through, which is why i am attempting to change the output in the 'if' statement on certain words.

Cheers
L
LoKii
Voice
Posts: 34
Joined: Wed Oct 21, 2009 3:59 am

Post by LoKii »

update:

I got it to work this way:

Code: Select all

proc proc_msgm {nick uhost hand arg} {
    set chan "#prototype"
    set line [string trim $arg]
    set items [split [string tolower $line]]
    set temp {
        "verify"
        "ident"
        "addhost"
        "pass"
    }
    foreach pattern $temp {
        foreach match [lsearch -all -inline $items $pattern] {
            putserv "PRIVMSG $chan :$nick has just messaged me, using the \002$pattern\002 command."
           return 1         
        }
    }
    puthelp "PRIVMSG $chan :$nick messaged me saying: '$line'"
    return 1
}
Using the lsearch.

Cheers everyone and sorry again for hijacking this thread :roll:
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

LoKii,
I'm not sure why you're using a second foreach-loop with lsearch in inline mode as the source. Just test the result from lsearch; if it's 0 or greater, there was a match, while -1 indicates there was no match.
My recommendation is something along these lines:

Code: Select all

proc proc_msgm {nick host handle text} {
  set items [split $text]
  set temp [list "verify" "ident" "addhost" "pass"]
  set chan "#prototype"

  foreach pattern $temp {
    if {[lsearch -nocase $items $pattern] >= 0} {
      puthelp "PRIVMSG $chan :$nick has just messaged me, using the \002$pattern\002 command."
      return 1
    }
  }
  puthelp "PRIVMSG $chan :$nick messaged me saying: '$text'"
  return 1
}
Last edited by nml375 on Sun Mar 10, 2013 12:06 pm, edited 1 time in total.
NML_375
L
LoKii
Voice
Posts: 34
Joined: Wed Oct 21, 2009 3:59 am

Post by LoKii »

@ nml375


Simple, I dont know either. Im a total n00b trying to get my scripts to work the way I imagine.

I will try out your suggestion and let you know in a bit :oops:

If I showed you my main script which is around 3000 lines by now, you would prolly shoot me for raping TCL.

Cheers for your help. :roll:
L
LoKii
Voice
Posts: 34
Joined: Wed Oct 21, 2009 3:59 am

Post by LoKii »

Your solution didnt quite work for me.

No matter what i write in a /msg bot , the result is ALWAYS:
LoKii has just messaged me, using the verify command.
I dont really understand why yet, but I'm sure I will figure it out once i understand what you meant with using the foreach-loop once.

In the mean time, my code is:

Code: Select all

proc proc_msgm {nick uhost hand arg} {
    global memo
    set chan "#prototype"
    set line [string trim $arg]
    set items [split [string tolower $line]]
    set temp {
        "verify"
        "ident"
        "addhost"
        "pass"
        "info"
        "voice"
        "halfop"
        "invite"
        "key"
        "op"
        "status"
        "notes"
    }
    set danger {
        "die"
        "jump"
        "reset"
    }
    if {[matchattr $nick n]} {
        return 1
    }
    foreach pattern $temp {
        foreach match [lsearch -all -inline $items $pattern] {
            putserv "PRIVMSG $chan :$nick has just messaged me, using the \002$pattern\002 command."
            return 1         
        }
    }
    foreach pattern $danger {
        foreach match [lsearch -all -inline $items $pattern] {
            putserv "PRIVMSG $chan :\002WARNING!\002 User \002$nick\002 has just attempted to use the \002$pattern\002 command."
            putserv "PRIVMSG $chan :Full output is: \002$arg\002."
            putserv "PRIVMSG $memo :send lokii Master, a user \002$nick\002 has just attempted to issue the \002$pattern\002 command on me via /msg. His full output was: \002$arg\002."
            return 1
        }
    }
    puthelp "PRIVMSG $chan :$nick messaged me saying: '$line'"
    return 1
}
Which works great, except I'm sure that your method is less resource-hungry.

BTW, i got my code based on a code that you have written in: http://forum.egghelp.org/viewtopic.php? ... ight=lists
Last edited by LoKii on Sun Mar 10, 2013 12:07 pm, edited 1 time in total.
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Sorry, made a minor mistake... :oops:
Should've tested for greater or equal to zero, not less than zero...

I'll update my previous post in a sec or two...
NML_375
L
LoKii
Voice
Posts: 34
Joined: Wed Oct 21, 2009 3:59 am

Post by LoKii »

nml375 wrote:Sorry, made a minor mistake... :oops:
Should've tested for greater or equal to zero, not less than zero...

I'll update my previous post in a sec or two...
Yup, now it works like a charm. I will try to understand the difference between yours and mine, to make sure that in the future, my code will be more effective.

Will convert my version into yours, and show it.

Many thanks for your help everyone :)
L
LoKii
Voice
Posts: 34
Joined: Wed Oct 21, 2009 3:59 am

Post by LoKii »

Update:

Final code and works like a charm. Now i got some reading to do to understand the difference.

Code: Select all

proc proc_msgm {nick host handle text} {
    global memo
    set items [split $text]
    set temp [list "verify" "ident" "addhost" "pass" "info" "voice" "halfop" "invite" "key" "op" "status" "notes"]
    set danger [list "die" "jump" "reset"]
    set chan "#prototype"
    if {[matchattr $nick n]} {
        return 1
    }
    foreach pattern $temp {
        if {[lsearch -nocase $items $pattern] >= 0} {
            puthelp "PRIVMSG $chan :$nick has just messaged me, using the \002$pattern\002 command."
            return 1
        }
    }
    foreach pattern $danger {
        if {[lsearch -nocase $items $pattern] >= 0} {
            putserv "PRIVMSG $chan :\002WARNING!\002 User \002$nick\002 has just attempted to use the \002$pattern\002 command."
            putserv "PRIVMSG $chan :Full output is: \002$text\002."
            putserv "PRIVMSG $memo :send lokii Master, a user \002$nick\002 has just attempted to issue the \002$pattern\002 command on me via /msg. His full output was: \002$text\002."
            return 1
        }
    }
    puthelp "PRIVMSG $chan :$nick messaged me saying: '$text'"
    return 1
}
Many thanks for your help :)
Post Reply