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]variable inside the proc

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


Joined: 09 Aug 2010
Posts: 45

PostPosted: Tue Jun 05, 2012 1:13 am    Post subject: [SOLVED]variable inside the proc Reply with quote

Hi,

I don't understand yet much about list operation in TCL. I just starting learning TCL tho' Very Happy I have question about calling variable inside the proc.

For example i have this list
Code:
set advert(words) "*http:* *www.* *.com*"


And i want to call that list inside the proc to match the kick reason.

Code:
foreach word $advert(words) {
       if {[string match -nocase [lindex $advert(words)] $txt] } {return 0}
   }


So i need it for my kick reason
Code:
putserv "KICK $chan $nick :spam match from $word not allowed!


But i got confused on the list operation command. It detects the whole advert(words) list. I still have no idea what list operation to use. Is it an lrange, lindex, or other. Please teach me. My code are so massy Sad

Thank you
_________________
Learning Knows No Boundaries!!


Last edited by gasak on Wed Jun 06, 2012 9:34 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: Tue Jun 05, 2012 12:32 pm    Post subject: Reply with quote

When using foreach-loops to iterate though lists, you specify an iterator-variable (in your code it's word), which will be updated with the next element in the list upon each iteration of the list. Thus, you should not use lindex on the list to extract the item.

Code:
foreach word $advert(words) {
  if {[string match -nocase $word $txt]} {...

_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3741
Location: Mint Factory

PostPosted: Tue Jun 05, 2012 1:50 pm    Post subject: Reply with quote

Also, in order to go to the next element in the list if a statement is false use continue not return . Example:
Code:

foreach word $advert(words) {
  if {![string match -nocase $word $txt]} continue

that means if the current element that is taken from the $advert(words) doesn't match the $txt then it will continue with the next element. In order to stop the iteration use break instead of continue.
_________________
Once the game is over, the king and the pawn go back in the same box.
Back to top
View user's profile Send private message
gasak
Halfop


Joined: 09 Aug 2010
Posts: 45

PostPosted: Tue Jun 05, 2012 11:42 pm    Post subject: Reply with quote

I tried but doesn't work..

Ok here's the full code:
Code:
set advban(time) "30"
set advban(chans) "#chan"
set advban(words) "*http*//* *http:* *www.* *.htm* *ftp*//* *www.*.co* */server*.*.*"
set advban(exempts) ""

bind pubm - "*" advban

proc advban {nick host hand chan txt} {
   global advban
   set advban(chans) [string tolower $advban(chans)]
   set chan [string tolower $chan]
   if {([string length [string trim $advban(chans)]] != 0) && ([lsearch -exact [split $advban(chans)] $chan] == -1)} {return 0}
   foreach exempt $advban(exempts) {
      if {[lsearch $txt $exempt]} {return 0}
   }
   foreach word $advban(words) {
       if {![string match -nocase $word $txt]} {continue}
   }
   if {![validuser $nick] && ![isop $nick $chan]} {

      set ban *!*@[lindex [split $host @] 1]
      putquick "MODE $chan +b $ban"
      putquick "KICK $chan $nick :Spam match from ($word) is not allowed here"
      timer $advban(time) {putquick "MODE $chan -b $ban"}
   }
}


I got 2 errors there. the $word on kick msg doesnt work and the timer also doesnt work. It says wrong $chan for the timer part.

Please help. Thanks.
_________________
Learning Knows No Boundaries!!
Back to top
View user's profile Send private message
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3741
Location: Mint Factory

PostPosted: Wed Jun 06, 2012 12:21 am    Post subject: Reply with quote

Code:

foreach element $list {
   if {whatever $element check you wish returns true} {
      do this action
   } else {
      do this second action as the if statement returned false
   }
}

In your case you should check each spoken word by the user and compare it with each element you have in the blackilst, but before that check if the word is not in the except list like this:
Code:

set found 0
foreach word [split $txt] {
   if {[lsearch -nocase $advban(exempts) $word] != -1} break
   foreach element [split $advban(words)] {
      if {![string match -nocase $word $element]} continue
      set found 1
      set badword $word
      break
   }
}

if {$found} {
   do whatever you wish as there has been a match with one of the words in the blacklist and that word has been stored in $badword variable
}

_________________
Once the game is over, the king and the pawn go back in the same box.
Back to top
View user's profile Send private message
gasak
Halfop


Joined: 09 Aug 2010
Posts: 45

PostPosted: Wed Jun 06, 2012 12:29 am    Post subject: Reply with quote

ok thanks caesar.. i'll give it a try now..
_________________
Learning Knows No Boundaries!!
Back to top
View user's profile Send private message
gasak
Halfop


Joined: 09 Aug 2010
Posts: 45

PostPosted: Wed Jun 06, 2012 12:42 am    Post subject: Reply with quote

caesar, i got this error:
Quote:
Tcl error [advban]: bad option "-nocase": must be -all, -ascii, -decreasing, -dictionary, -exact, -glob, -increasing, -inline, -integer, -not, -real, -regexp, -sorted, or -start

_________________
Learning Knows No Boundaries!!
Back to top
View user's profile Send private message
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3741
Location: Mint Factory

PostPosted: Wed Jun 06, 2012 4:34 am    Post subject: Reply with quote

That's cos you have an outdated TCL library version. Anyway, replace:
Code:

   if {[lsearch -nocase $advban(exempts) $word] != -1} break

with:
Code:

   if {[lsearch -equal $advban(exempts) [string tolower $word]] != -1} break

Btw, you should move the:
Code:

if {![validuser $nick] && ![isop $nick $chan]} {

after the global advban as it makes more sense to be there if you wish to skip a user if it's known to the bot AND is a channel operator.
_________________
Once the game is over, the king and the pawn go back in the same box.
Back to top
View user's profile Send private message
gasak
Halfop


Joined: 09 Aug 2010
Posts: 45

PostPosted: Wed Jun 06, 2012 8:09 am    Post subject: Reply with quote

The same error caesar
Quote:
Tcl error [spamban]: bad option "-equal": must be -all, -ascii, -decreasing, -dictionary, -exact, -glob, -increasing, -inline, -integer, -not, -real, -regexp, -sorted, or -start


Is it correct the placement of my code?
Code:
proc advban {nick host hand chan txt} {
   global advban
   if {![validuser $nick] && ![isop $nick $chan]} {
   set advban(chans) [string tolower $advban(chans)]
   set chan [string tolower $chan]
   if {([string length [string trim $advban(chans)]] != 0) && ([lsearch -exact [split $advban(chans)] $chan] == -1)} {return 0}
   foreach exempt $advban(exempts) {
      if {[lsearch $txt $exempt]} {return 0}
   }
  set found 0
   foreach word [split $txt] {
   if {[lsearch -equal $advban(exempts) [string tolower $word]] != -1} break
   foreach element [split $advban(words)] {
      if {![string match -nocase $word $element]} continue
      set found 1
      set badword $word
      break
   }
}

      if {$found} {
      set ban *!*@[lindex [split $host @] 1]
      putquick "MODE $chan +b $ban"
      putquick "KICK $chan $nick :Spam match from ($word) is not allowed here"
      timer $advban(time) {putquick "MODE $chan -b $ban"}
   }
}


anyway, should i remove this code?
Code:
foreach exempt $advban(exempts) {
      if {[lsearch $txt $exempt]} {return 0}
   }

Since you already called it inside.

Thanks.
_________________
Learning Knows No Boundaries!!
Back to top
View user's profile Send private message
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3741
Location: Mint Factory

PostPosted: Wed Jun 06, 2012 8:29 am    Post subject: Reply with quote

Something like this:
Code:

set advban(time) "30"
set advban(chans) "#chan"
set advban(words) "*http*//* *http:* *www.* *.htm* *ftp*//* *www.*.co* */server*.*.*"
set advban(exempts) ""

bind pubm - "*" advban

proc advban {nick host hand chan txt} {
   global advban
   if !{[string length $advban(chans)]} return
   if {[lsearch -exact $advban(chans) $chan] == -1} return
   if {[validuser $nick] && [isop $nick $chan]} return
   set found 0
   foreach word [split $txt] {
      set word [string tolower $word]
      if {[lsearch -equal $advban(exempts) $word] != -1} break
      foreach element [split $advban(words)] {
        if {![string match -nocase $word $element]} continue
        set found 1
        set badword $word
        break
      }
   }
   if {$found} {
      set ban *!*@[lindex [split $host @] 1]
      putquick "MODE $chan +b $ban"
      putquick "KICK $chan $nick :Spam match from ($badword) is not allowed here"
      timer $advban(time) [list "pusmode $chan -b $ban"]
   }
}

Haven't tested so let me know if you get any issues.

Edit: fixed typo.
_________________
Once the game is over, the king and the pawn go back in the same box.


Last edited by caesar on Wed Jun 06, 2012 10:15 am; edited 1 time in total
Back to top
View user's profile Send private message
gasak
Halfop


Joined: 09 Aug 2010
Posts: 45

PostPosted: Wed Jun 06, 2012 9:30 am    Post subject: Reply with quote

Hi caesar,

I just tested it but it doesn't work at all. Nothings happen when the badwords trigger said on channel.
_________________
Learning Knows No Boundaries!!
Back to top
View user's profile Send private message
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3741
Location: Mint Factory

PostPosted: Wed Jun 06, 2012 10:15 am    Post subject: Reply with quote

Oh sorry, forgot a ! in:
Code:

if {[string length $advban(chans)]} return

that should be:
Code:

if {![string length $advban(chans)]} return

_________________
Once the game is over, the king and the pawn go back in the same box.
Back to top
View user's profile Send private message
nml375
Revered One


Joined: 04 Aug 2006
Posts: 2857

PostPosted: Wed Jun 06, 2012 1:17 pm    Post subject: Reply with quote

I'd suggest something along these lines;
Iterate through each badword-pattern, and get a list of matching words from the spoken text.
Since you'd like to use wildcards in your exempts-list, we'll have to iterate through this list for each match, and see if it should be exempted. If it should be exempted, move on to the next match; else, ban the user and be done with it.

Further, instead of manually adding the ban, kicking the user, and setting up a timer to finally remove it, why not just use the newchanban command with a custom expire-time?

The above converted to code:
Code:
set advban(time) "30"
set advban(chans) [list "#chan"]
set advban(words) [list "*http*//*" "*http:*" "*www.*" "*.htm*" "*ftp*//*" "*www.*.co*" "*/server*.*.*"]
set advban(exempts) [list]

bind pubm - "*" advban

proc advban {nick host hand chan txt} {
  global advban
  set advban(chans) [string tolower $advban(chans)]
  set chan [string tolower $chan]
  set items [split [string tolower $txt]]
  if {[validuser $hand] || [isop $nick $chan] || ([llength $advban(chans)] > 0 && [lsearch -exact $advban(chans) $chan] == -1)} {
    return 0
  }

  foreach pattern $advban(words) {
    foreach match [lsearch -all -inline $items [string tolower $pattern]] {
      set exempt 0
      foreach exception $advban(exempts) {
        if {[string match -nocase $exception $match]} {
          set exempt 1
          break
        }
      }
      if {$exempt} {
        continue
      } else {
        newchanban $chan "*!*@[lindex [split $host "@"] 1]" "advban.tcl" "Spam match from ($match) is not allowed here" $advban(time)
        return 1
      }
    }
  }
}


Or, if we skip the wildcard matching of exempts:
Code:
set advban(time) "30"
set advban(chans) [list "#chan"]
set advban(words) [list "*http*//*" "*http:*" "*www.*" "*.htm*" "*ftp*//*" "*www.*.co*" "*/server*.*.*"]
set advban(exempts) [list "*example.com*"]

bind pubm - "*" advban

proc advban {nick host hand chan txt} {
  global advban
  set advban(chans) [string tolower $advban(chans)]
  set chan [string tolower $chan]
  set items [split [string tolower $txt]]
  if {[validuser $hand] || [isop $nick $chan] || ([llength $advban(chans)] > 0 && [lsearch -exact $advban(chans) $chan] == -1)} {
    return 0
  }

  foreach pattern $advban(words) {
    foreach match [lsearch -all -inline $items $pattern] {
      if {[lsearch -exact $advban(exempts) $match]} {
        continue
      } else {
        newchanban $chan "*!*@[lindex [split $host "@"] 1]" "advban.tcl" "Spam match from ($match) is not allowed here" $advban(time)
        return 1
      }
    }
  }
}

_________________
NML_375, idling at #eggdrop@IrcNET
Back to top
View user's profile Send private message
gasak
Halfop


Joined: 09 Aug 2010
Posts: 45

PostPosted: Wed Jun 06, 2012 9:32 pm    Post subject: Reply with quote

Thanks a lot nml375. It works great Smile
_________________
Learning Knows No Boundaries!!
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