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.

Relay Script

Help for those learning Tcl or writing their own scripts.
L
Lu5ck
Halfop
Posts: 43
Joined: Thu Dec 07, 2006 8:58 am

Relay Script

Post by Lu5ck »

Hi there,

I doing a relay script, but I need help in setting a repeated spam protection. As in if there is repeated text, the script won't repeat the same text for a certain time.

How can I go about doing this?

Regards,
Lu5ck
L
Lu5ck
Halfop
Posts: 43
Joined: Thu Dec 07, 2006 8:58 am

Post by Lu5ck »

Hi all,

I did a repeat spam in it, however, it is unable to process fast enough for the huge amount of data flowing through it. How can I further improve the repeat system, I am currently using timer for it.

Code: Select all

proc repeatCheck {iphost} {
 # Access and Store GLOBAL
 global repeat repeat_count

 # Check for existence, add if it didn't exist
 if {![info exists repeat_count($iphost)] && [lsearch -exact $repeat 0] == -1} {
  set repeat_count($iphost) 0
 }

 # Increase count and set timer to remove it
 incr repeat_count($iphost) 1
 utimer [lindex $repeat 1] [list unset -nocomplain repeat_count($iphost)]

 # Do what when reach the maximum repeat
 if {$repeat_count($iphost) == [lindex $repeat 0]} {
  return 1
 }

 return 0
}
Regards,
Lu5ck
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

Possibly use separate variables, rather than multiple variables in a list (repeat).

There is a conditon in your script that might cause multiple timers to unset the same array index. Although having pending timers does'nt take processing-time in itself, the unset command would be called numerous times, blocking other executions.

Could the queue-system (with throttling) be an issue?
NML_375
L
Lu5ck
Halfop
Posts: 43
Joined: Thu Dec 07, 2006 8:58 am

Post by Lu5ck »

Hi there,

Thanks for the reply. I notice another problem, if a user repeat 5 lines within 1 or 2s. The check won't be fast enough to consider them as repeat. I will look into the variable you mention.

Regards,
Lu5ck
L
Lu5ck
Halfop
Posts: 43
Joined: Thu Dec 07, 2006 8:58 am

Post by Lu5ck »

Hi there,

Thank you for the advice, it is indeed the timers that been created without control that is causing the problem. I did a check on the timer to make sure it don't exist before creating them. However, is there a better way to do this timer check as it is slow to loop through the timers as I did them.

Code: Select all

proc repeatCheck {iphost} {
 # Access and Store GLOBAL
 global repeat repeat_count

 # Check for existence, add if it didn't exist
 if {![info exists repeat_count($iphost)]} {
  lappend repeat_count($iphost) 0
 }

 # Increase count and set timer to remove it
 incr repeat_count($iphost)

 foreach utimer [utimers] {
  if {[string match "unset repeat_count($iphost)" [lindex $utimer 1] ]} {
   set timerCheck 1
  }
 }

 if {![info exists timerCheck]} {
  utimer [lindex $repeat 1] "unset repeat_count($iphost)"
 } else {
  unset timerCheck
 }

 # Do what when reach the maximum repeat
 if {$repeat_count($iphost) > [lindex $repeat 0]} {
  return 1
 }

 return 0
}
Regards,
Lu5ck
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

I guess an ugly check would be to simply use "string first" or "string match", and skip the foreach loop. Not sure how much performace you'd gain however.

One thing that might improve it slightly, is to replace your "string match" with "string equal", since the latter does a character-by-character comparison, and does'nt care 'bout wildcard matching.

Another ugly hack might be to assume there is a timer already running, if "repeat_count($iphost)" already exists upon entering the proc, as a previous invocation would've started the timer if repeat_count($iphost) had been set, and if the timer had completed, repeat_count($iphost) would've been unset.
NML_375
L
Lu5ck
Halfop
Posts: 43
Joined: Thu Dec 07, 2006 8:58 am

Post by Lu5ck »

Hi there,

Thank you for your advice. I have decided to go with check of "repeat_count($iphost)" and assume if it exist then there will be timer exist as well. It will be more efficient in performance compare with the loop check in timer. So far, there isn't any problem running it. Once again, Thanks.

Regard,
Lu5ck
User avatar
sKy
Op
Posts: 194
Joined: Thu Apr 14, 2005 5:58 pm
Location: Germany

Post by sKy »

May you tell me what problem you want to solve with that script (relay what?)?
socketapi | Code less, create more.
L
Lu5ck
Halfop
Posts: 43
Joined: Thu Dec 07, 2006 8:58 am

Post by Lu5ck »

Hi there,

Thanks for offering your help. I have found yet another bug in the script. Since the relay script uses socket to connect to another IRC network. All data is in its RAW form. I notice a problem in PRIVMSG raw where when there is braces "{ or }", the script will end up in error. I tried using regular expression to remove the "{ or }", it don't seem to works. Any suggestion in doing this? All RAW data is in this variable call "$arg".

Regards,
Lu5ck
L
Lu5ck
Halfop
Posts: 43
Joined: Thu Dec 07, 2006 8:58 am

Post by Lu5ck »

Hi there,

I read through some stuff and it seem split is able to fix the problem. I have add it into the script and see if it fix it.

Regards,
Lu5ck
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

If you get errors such as that, it usually means you are mixing lists and strings. Although split does fix these issues at some times (especially when you use list commands on strings), it's really important to understand why you should use split in certain situations.

Simply put tho, commands such as lindex, lrange, lreplace, foreach, join and many others (check their respective manpages) operate on lists, and might break on strings.

Commands such as "string" are generally not list-safe, that is, if used on a list it might damage the list-structure, rendering it unusable as list (causing lindex, etc to break)
NML_375
L
Lu5ck
Halfop
Posts: 43
Joined: Thu Dec 07, 2006 8:58 am

Post by Lu5ck »

Hi there,

Thanks for the reply. I have added split to most "lindex". After going through the third time. I notice I miss out one split on one of the lindex. I added it and it seem to be running smooth now. It still need more testing though. Now I got another question, will quote cause error to script?

Regards,
Lu5ck
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

First off, don't use split just because you use lindex. Only use split if you need to convert a string into a list. That is, keep track of wether the data is a list or a string. Using split on lists may result in undesired results aswell.

"" is used as bounds of data that should be preprocessed, doing variable, command, and escape-evaluations. Any " within such data-block must be escaped.

A perhaps better description might be found here
NML_375
L
Lu5ck
Halfop
Posts: 43
Joined: Thu Dec 07, 2006 8:58 am

Post by Lu5ck »

Hi there,

Thanks for the info. Yes, I didn't add split to all "lindex". To be accurate, I add them to "lindex" that need to process the "$arg" and all variable that related to that. I guess I need to rephrase my question regarding the quote. If there is quote in the variable call "temp", will it cause error to script?

Regards,
Lu5ck
n
nml375
Revered One
Posts: 2860
Joined: Fri Aug 04, 2006 2:09 pm

Post by nml375 »

To be honest, I can't even find the variable "temp" within the piece of code you've posted...

Generally, quotes should not cause problems with neither lists or strings..
Of course, this code will fail, but due to incorrect structures...

Code: Select all

set myvar "Testing "in string"
Problem here is that the first parameter is terminated at the second ", but is directly followed by additional characters. Either you've forgotten to escape the ", or you accidentally grouped two parameters (forgot a space). Tcl can't figure out which, and barks.
Correct code in the above example:

Code: Select all

set myvar "Testing \"in string"
set myvar {Testing "in string}
Now, using myvar with any command that expects a string as parameter (where $myvar is used on the commandline) will work perfectly.
Ofcourse, $myvar should NOT be used with any command that expects a list, since it is a string.

A list would be created as such:

Code: Select all

#Make {Testing "in string} a single list-element:
set myvar [list "Testing \"in string"]
set myvar [list {Testing "in string}]

#Make Testing "in string separate list elements:
set myvar [list Testing \"in string]
set myvar [list Testing {"in} string]
NML_375
Post Reply