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 script to say all nicks from chan

Help for those learning Tcl or writing their own scripts.
u
unb0rn
Voice
Posts: 26
Joined: Mon Sep 08, 2008 8:14 am

Help with script to say all nicks from chan

Post by unb0rn »

I've been using this script for quite some time now, but some people it's abusing, and i want to add some protection like:
if {[set t [expr {[unixtime]-$usedcmd}]] < 5} {
puthelp "privmsg $chan :wait [expr {5-$t}] second(s) to use again the script"
so they have to wait the time that i decided, to use the script again, in seconds...
the script is:
set channelz [split [string tolower "#chan"]]
bind pub -|- !nicks spam:nicklist

proc spam:nicklist {nick uhost hand chan text} {
if {![string length $text]} {
set text $chan
} elseif {![validchan $text]} {
putserv "privmsg $chan :Invalid channel name ($text)."
return
}
if {[lsearch -exact $::channelz [string tolower $text]]} {
putserv "privmsg $chan :ALL NICKS FROM CHAN!!!"
putserv "privmsg $chan :[join [chanlist $chan] ", "]"
}
}
can someone help me out here?
i think it's easy, but i can't put it to work correctly ;/
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

I didn't test the code snippet below but it looks OK. However, I would wish to stress one very important point. If the number of nicks in the target channel is such that it causes an output greater than the IRCD will accept then there will be no output at all.

Code: Select all

set vChannels "#chan1 #chan2"

bind PUB - !nicks pNicklist

proc pNicklist {nick uhost hand channel txt} {
  global vChannels
  switch -- [llength [split $txt]] {
    0 {set tchan $channel}
    1 {set tchan $txt}
  }
  if {[info exists tchan]} {
    if {[regexp {^#} $tchan]} {
      if {[validchan $tchan]} {
        if {[botonchan $tchan]} {
          if {[lsearch -exact [string tolower $vChannels] [string tolower $tchan]] != -1} {
            putserv "PRIVMSG $channel :[join [chanlist $tchan] ", "]" 
          }
        } else {putserv "PRIVMSG $channel :-error- bot is not currently monitoring $tchan"}
      } else {putserv "PRIVMSG $channel :-error- bot does not have a channel record for $tchan"}
    } else {putserv "PRIVMSG $channel :-error- $tchan is not in the format of a valid channel name"}
  } else {putserv "PRIVMSG $channel :-error- correct syntax is !nicks ?#channel?"}
}
I must have had nothing to do
u
unb0rn
Voice
Posts: 26
Joined: Mon Sep 08, 2008 8:14 am

Post by unb0rn »

How do i set the limit of time of commands that the users can use?

ex:
someone: !nicks
bot: ALL NICKS FROM THE CHANNEL
someone: !nicks
bot: you have to wait 5s, before using the command again

I want to put a selected time, so they have to wait a couple of seconds, and not flooding the bot/server.

and how do i put a message before the eggdrop says all nicks from the channel?
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

Code: Select all

set vChannels "#chan1 #chan2"

set vFlood 0

bind PUB - !nicks pNicklist

proc pNicklist {nick uhost hand channel txt} {
  global vChannels vFlood
  if {!$vFlood} {
    switch -- [llength [split $txt]] {
      0 {set tchan $channel}
      1 {set tchan $txt}
    }
    if {[info exists tchan]} {
      if {[regexp {^#} $tchan]} {
        if {[validchan $tchan]} {
          if {[botonchan $tchan]} {
            if {[lsearch -exact [string tolower $vChannels] [string tolower $tchan]] != -1} {
              putserv "PRIVMSG $channel :ALL NICKS FROM $tchan"
              putserv "PRIVMSG $channel :[join [chanlist $tchan] ", "]"
            }
          } else {putserv "PRIVMSG $channel :-error- bot is not currently monitoring $tchan"}
        } else {putserv "PRIVMSG $channel :-error- bot does not have a channel record for $tchan"}
      } else {putserv "PRIVMSG $channel :-error- $tchan is not in the format of a valid channel name"}
    } else {putserv "PRIVMSG $channel :-error- correct syntax is !nicks ?#channel?"}
    set vFlood 1
    utimer 5 [list set vflood 0]
  } else {putserv "PRIVMSG $channel :-flood- please try again later"}
}
I must have had nothing to do
u
unb0rn
Voice
Posts: 26
Joined: Mon Sep 08, 2008 8:14 am

Post by unb0rn »

Thank you, it's working perfectly.
u
unb0rn
Voice
Posts: 26
Joined: Mon Sep 08, 2008 8:14 am

Post by unb0rn »

I detected a problem ;x
I didn't change the time of wait before using the script again, to prevent flood, but, i do the command !nicks, and even if a wait 5s, or more(i tried waiting 2m, and the only thing that i see, is the message from flood), the command doesn't work, it always shows the message from the flood protection.

What could be?


btw, i have this from another script that i've done, that works pretty much the same way, but for another thing, it's possible to use this(what im about to show) on this script?
set usedcmd [expr {[unixtime]-5}]

proc cmd {nick uhost hand chan arg} {
global usedcmd sex
if {[set t [expr {[unixtime]-$usedcmd}]] < 5} {
puthelp "privmsg $chan :Wait [expr {5-$t}] sc(s) or gtfo"
return 0
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

I can't think why the script has stuck with the flood setting but simply rehashing the bot would fix things.

Yes you could use something similar to the code you have seen in a previous script.

My personal prefference in these situations is to unbind the pub bind for 5 seconds to prevent its reuse within that timeframe but that method doesnt give easy opportunity to output a flood message.
I must have had nothing to do
u
unb0rn
Voice
Posts: 26
Joined: Mon Sep 08, 2008 8:14 am

Post by unb0rn »

Once again i have to thank you for your help, but the reason why i don't know, but if i use the script, the only way to make it work again, i have to rehash it... ;/

i've been editing stuff, and i detected that if a change the "1" to "0", the problem stops, but the script doesn't stop when people flood it, and the "utimer" it's not doing nothing, 'cos i've tried to change from "5" to "1" and "0", and it's the same...
utimer 5 [list set vflood 0]

Can you please help me using the other part of the script that i've pasted here, on this one?[/b][/quote]
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

set vFlood 1 
utimer 5 [list set vflood 0]
There is the issue. The script tracks the global variable vflood and uses the global command to associate the local references as global ones. This works fine to set vflood to 1, meaning it's been used recently. The problem is, this timer will execute after the proc ends, meaning the association to the global variable vflood is lost. The set vflood 0 will occur in local space as a local variable and is immediately destroyed. The global variable vflood will remain set to 1, forever. Back and forth. The same 1.

Code: Select all

utimer 5 [list set ::vflood 0]
We can use the global namespace identifier (::) and prefix vflood with this and it will now work, and remain tied to the global variable vflood. When the timer is invoked, it will return the global variable vflood to 0 and all is well in the world.
Last edited by speechles on Wed Mar 25, 2009 5:00 pm, edited 1 time in total.
D
DaRkOoO
Halfop
Posts: 67
Joined: Sat Sep 27, 2008 7:27 am

Post by DaRkOoO »

This dont work.If there is,for example,more than 50 nicks in channel bot will say just how much he can say in one msg,so lets say he can say about 40 nicks,and what about rest of nicks?
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

I have tested the script pretty much as it stands, after increasing the flood time to a realistic value of 30 seconds. It works fine. Perhaps a return command at the end of the proc would be proper, as below (not convinced though that it would matter in this instance).

One other thing that could I suppose effect scripts. When I copy/paste from this site to my text editor, I get a whitespace at the end of each line. If that happens to you, get rid of them before you load the script on the bot.

Code: Select all

set vChannels "#EggTCL"

set vFlood 0

bind PUB - !nicks pNicklist

proc pNicklist {nick uhost hand channel txt} {
  global vChannels vFlood
  if {!$vFlood} {
    switch -- [llength [split $txt]] {
      0 {set tchan $channel}
      1 {set tchan $txt}
    }
    if {[info exists tchan]} {
      if {[regexp {^#} $tchan]} {
        if {[validchan $tchan]} {
          if {[botonchan $tchan]} {
            if {[lsearch -exact [string tolower $vChannels] [string tolower $tchan]] != -1} {
              putserv "PRIVMSG $channel :[join [chanlist $tchan] ", "]"
            }
          } else {putserv "PRIVMSG $channel :-error- bot is not currently monitoring $tchan"}
        } else {putserv "PRIVMSG $channel :-error- bot does not have a channel record for $tchan"}
      } else {putserv "PRIVMSG $channel :-error- $tchan is not in the format of a valid channel name"}
    } else {putserv "PRIVMSG $channel :-error- correct syntax is !nicks ?#channel?"}
    set vFlood 1
    utimer 30 [list set vFlood 0]
  } else {putserv "PRIVMSG $channel :-flood- please try again later"}
  return 0
}
This is the output at in the channel #EggTCL on DALnet :-

[20:45] <@arfer> !nicks
[20:45] <@Baal> Baal, Colossus, McKay, arfer
[20:45] <@arfer> !nicks
[20:45] <@Baal> -flood- please try again later
[20:45] <@arfer> !nicks
[20:45] <@Baal> -flood- please try again later
[20:45] <@arfer> !nicks
[20:45] <@Baal> -flood- please try again later
[20:46] <@arfer> !nicks
[20:46] <@Baal> Baal, Colossus, McKay, arfer

Following the first successful use of the command !nicks, subsequent use within the 30 seconds wait time results in the -flood- message. after 30 seconds the command responds again as expected.

The command has to get from your IRC client to the server and then from the server to your bot which then executes the code, responds to the server which responds to your IRC client. Whilst the Tcl code on your bot probably takes milliseconds to execute per cycle, the to'ing and fro'ing possibly takes up most if not all of the 5 seconds. Hence the next command works even though it appears to you to be within the 5 seconds flood time.

Anyway, I can now confirm that there is nothing wrong with the code (in my opinion). I don't intend modifying it further.
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 »

DaRkOoO wrote:This dont work.If there is,for example,more than 50 nicks in channel bot will say just how much he can say in one msg,so lets say he can say about 40 nicks,and what about rest of nicks?
Incorporate a wordwrap procedure, such as this one by user.

Code: Select all

putserv "PRIVMSG $channel :[join [chanlist $tchan] ", "]"
Change that above to this below...

Code: Select all

foreach line [wordwrap [join [chanlist $tchan] ", "]]] { putserv "privmsg $chan :$line" }
User avatar
arfer
Master
Posts: 436
Joined: Fri Nov 26, 2004 8:45 pm
Location: Manchester, UK

Post by arfer »

Yes I agree. I warned the original poster about the issue of many nicks exceeding the allowed text length in my first respionse to this thread.
I must have had nothing to do
D
DaRkOoO
Halfop
Posts: 67
Joined: Sat Sep 27, 2008 7:27 am

Post by DaRkOoO »

I get this :

Code: Select all

[22:27] Tcl error [pNicklist]: invalid command name "wordwrap"
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

DaRkOoO wrote:I get this :

Code: Select all

[22:27] Tcl error [pNicklist]: invalid command name "wordwrap"
Well, did you include the procedure by user in the script by arfer? If not, then of course it's an invalid command name. The procedure supporting it must be added to the script...

Code: Select all

proc wordwrap {str {len 70} {splitChr { }}} {
   set out [set cur {}]; set i 0
   foreach word [split [set str][unset str] $splitChr] {
      if {[incr i [string len $word]]>$len} {
         lappend out [join $cur $splitChr]
         set cur [list $word]
         set i [string len $word]
      } {
         lappend cur $word
      }
      incr i
   }
   lappend out [join $cur $splitChr]
} 
Add the above to the bottom of the script (Full credit goes to user for the above, find the thread here).
Post Reply