| View previous topic :: View next topic |
| Author |
Message |
tmyoungjr Voice
Joined: 24 Aug 2007 Posts: 14
|
Posted: Wed Jan 07, 2009 11:22 am Post subject: flood check |
|
|
I have a real simple script that i found here in the forums :
| Code: |
bind pub - !fact pub_fact
proc pub_fact {n u h c t} {
set fl [open fact.txt]
set data [read $fl]
close $fl
set lines [split $data \n]
set randline [lindex $lines [rand [llength $lines]]]
putserv "privmsg $c $randline"
}
|
i'll modify it a bit for my needs. what i'm looking for tho is flood control. i want to limit the # of times this script will return anything (something like say 1 request every minute or some such). i've found many scripts with flood control built in, but they all seem excessively complicated for my needs. any assistance would be great. |
|
| Back to top |
|
 |
arfer Master

Joined: 26 Nov 2004 Posts: 436 Location: Manchester, UK
|
Posted: Wed Jan 07, 2009 2:53 pm Post subject: |
|
|
bind pub - !fact pub_fact
proc pub_fact {n u h c t} {
global varTimer
if {![info exists varTimer]} {
set varTimer 1
utimer 60 [unset varTimer]
set fl [open fact.txt]
set data [read $fl]
close $fl
set lines [split $data \n]
set randline [lindex $lines [rand [llength $lines]]]
putserv "privmsg $c :$randline"
}
return 0
} |
|
| Back to top |
|
 |
tmyoungjr Voice
Joined: 24 Aug 2007 Posts: 14
|
Posted: Wed Jan 28, 2009 5:28 pm Post subject: |
|
|
| thank you - this works wonderfully |
|
| Back to top |
|
 |
arfer Master

Joined: 26 Nov 2004 Posts: 436 Location: Manchester, UK
|
Posted: Fri Jan 30, 2009 9:23 pm Post subject: |
|
|
I know you said the above worked but recent coding I have done on something unrelated has caused me to rethink the solution I provided, as a generic means of preventing flood. I found the solution below to be more reliable.
| Code: |
bind pub - !fact pub_fact
proc pub_fact {n u h c t} {
unbind pub - !fact pub_fact
set fl [open fact.txt]
set data [read $fl]
close $fl
set lines [split $data \n]
set randline [lindex $lines [rand [llength $lines]]]
putserv "privmsg $c :$randline"
utimer 60 [list bind pub - !fact pub_fact]
return 0
}
|
|
|
| Back to top |
|
 |
TCL_no_TK Owner

Joined: 25 Aug 2006 Posts: 509 Location: England, Yorkshire
|
Posted: Mon Feb 02, 2009 7:25 am Post subject: |
|
|
| Code: | set fl [open fact.txt]
set data [read $fl] |
Replace with
| Code: | set fs [file size "fact.txt"]
set fl [open fact.txt]
set data [read $fl $fs] |  _________________ TCL the misunderstood |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Mon Feb 02, 2009 12:14 pm Post subject: |
|
|
TCL_no_TK:
What would the purpose of such a modification be?
Also, the extended syntax of read specifies the number of characters to read, while file size returns the number of bytes. Which certain charsets, such as UTF-8, one character may consist of several bytes. You will get away with this, as read, for normal files, reads as much as "numChars" charaters, or up until EOF, which ever comes first. Should the channelId however have been a serial port, the read command would block until the specific amount of characters have been recieved (of course, file size would not be useful on a serial port in the first place).
The point being, there is no good reason for specifying the number of characters to read, should you desire to read the whole file. _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
TCL_no_TK Owner

Joined: 25 Aug 2006 Posts: 509 Location: England, Yorkshire
|
Posted: Tue Feb 03, 2009 8:58 am Post subject: |
|
|
Performance
| Quote: | | ... there is one trick that might be necessary. Determine the size of the file first, then 'read' that many bytes. This allows the channel code to optimize buffer handling (preallocation in the correct size). I don't know anymore who posted this first. But you only need this for Tcl 8.0. This is something for the Tcl Performance page as well. | from How do I read and write files in Tcl _________________ TCL the misunderstood |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Tue Feb 03, 2009 12:38 pm Post subject: |
|
|
That performance-issue would be restricted to Tcl 8.0, and would still be flawed with the byte vs char issue...
In any case, I fail to see how that is related to the topic.
@tmyoungjr:
I believe user posted a very flexible throttling-mechanism that could easily be adopted to your script.
Check this post: http://forum.egghelp.org/viewtopic.php?p=75097#75097
arfer's approach is interresting, yet may cause the script to stop responding should any I/O-errors occur during the reading. Would probably be a good idea to move the utimer to the top of the proc.
Also worth mentioning, is that this will keep resetting the bind-counter every time it triggers.
A third option would be to simply use timestamps, removing the need for any timers or cleanup. Example posted below:
| Code: | proc throttle {id time} {
if {[info exists ::throttle($id)] && $::throttle($id) > [clock seconds]} {
return 0
}
set ::throttle($id) [expr [clock seconds] + $time]
return 1
}
proc myproc {} {
if {[throttle "theid" 60]} {
#we're ok, do the good stuff here
} {
#still throttle'd, do nothing
return 0
}
} |
_________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
|