I wanted to write a tcl script which looks if a user is registered at the services of the irc-network. That was no great problem but now another proc should use it. Both use the global variable isregged. Then there are the two procs:
bind msg -|- vhost setvhost
bind raw * 615 modereturn
the setvhost proc uses:
set isregged ""
putserv "WHOIS $nick"
vwait isregged
if the user has usermode +r set $isregged will be 1 else 0, but I always get: Tcl error [setvhost]: can't wait for variable "isregged": would wait forever
So I tried to use a while loop (yes, i know that's a bad idea)
set antiloop 0
while {$antiloop < 9999999} {
if {$isregged != ""} {break}
incr antiloop
}
but if I use that loop the modereturn proc is never started. So how can I tell the setvhost proc to wait until $isregged is changed?
In this situation, you are telling the script to wait for a variable, that will never get set. vwait is used to process background functions until the var is set, but in Tcl, there are no standard backgroud Tcl functions.
As for the while loop. You are making the same code execute over and over again. Unless the command that actualy set's the var is triggered in the while look, it will never change. IE, it will remain on that part of the script, and never process the incoming command to set the isreg var.
One way around it is to use utimers. Call a script every 1 second, and see if the var has been set. If not, re-start the utimer. If set, bypass the timer restart, and run the rest of the script.
In the timer version, eggdrop is able to process other incoming IRC traffic between timer runs. In the others, because the script never gives control back to eggdrop, the IRC traffic that causes the setting change, is never run.
bind raw - 615 raw:615
bind msg -|- vhost setvhost
trace variable isregged w trace:isregged
proc setvhost {nick uhost hand arg} {
global isregged isregged_timers
putquick "WHOIS $nick" -next
set lnick [string tolower $nick]
set isregged_timers($lnick) [utimer 5 "set isregged($lnick) 0"]
}
proc raw:615 {from numeric arg} {
global isregged isregged_timers
scan $arg "%s" nick
set lnick [string tolower $nick]
if {[info exists isregged_timers($lnick)]} {
killutimer $isregged_timers($lnick)
unset isregged_timers($lnick)
set isregged($lnick) 1
}
}
proc trace:isregged {variable nick cmd} {
global isregged isregged_timers
if {$isregged($nick) == 1} {
putlog "$nick is registered"
} else {
unset isregged_timer($nick)
putlog "$nick is not registered"
}
unset isregged($nick)
}
handles more than one person doing /msg <bot> vhost .. handles timeout incase the server takes a long ass time to respond to the WHOIS .. doesn't handle the same person doing /msg <bot> vhost more than once within the amount of time it takes to reach the timeout (this can be fixed easily w/ a bit better design).