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.

Problems with vwait or: waiting for variables to be set

Old posts that have not been replied to for several years.
Locked
i
iceblox

Problems with vwait or: waiting for variables to be set

Post by iceblox »

Hi,

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?
p
ppslim
Revered One
Posts: 3914
Joined: Sun Sep 23, 2001 8:00 pm
Location: Liverpool, England

Post by ppslim »

You can't make it wait.

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.
i
iceblox

Post by iceblox »

Thanks. Hmm, somehow the timer solution sounds as if it can process only 1 request at once, but I will try it :)
g
guppy
eggdrop engineer
Posts: 199
Joined: Mon Sep 24, 2001 8:00 pm
Location: Canada
Contact:

Post by guppy »

I dunno what numeric 615 is however (so I'll guess it looks like this: :server 615 <nickname> :Is registered) ... you could something like this:

Code: Select all


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).
Locked