mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Mar 2009
Posts: 2
W
Bowl of petunias
OP Offline
Bowl of petunias
W
Joined: Mar 2009
Posts: 2
Given the following code, you can see that im trying to find out if $network and $chan are seen after using a timer in !start.

Code:
on *:TEXT:!start:#test: _start
on *:INPUT:#test: if ($1 == !start) _start

alias _start {
  echo -a I can see both $network and $chan here
  .timer 1 5 _test
}

alias _test { echo -a but I cant see both $network and $chan here }



I found that $network is seen, but not $chan by observing the 2nd of the 2 echos, where #test is missing:
Code:
I can see both After-All and #test here
but I cant see both After-All and here


Am I doing something wrong? I wrote a massive script that assumed both $network and $chan are seen before AND after executing a timer. Should it be like that or is this a bug? Further, is there some way to make $chan be seen without adding an argument to $_test(arg)?

Joined: Jul 2007
Posts: 1,129
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
Change the $chan in the second alias to $active
Code:
alias _test { echo -a but I cant see both $network and $active here }

Last edited by Tomao; 05/03/09 08:06 PM.
Joined: Dec 2002
Posts: 2,962
S
Hoopy frood
Offline
Hoopy frood
S
Joined: Dec 2002
Posts: 2,962
This is to be expected. When calling an alias directly from an event the context of that event (identifiers like $chan, $nick, etc.) is passed to it. That context is not retained with timers so when the _test alias is called upon the timer being triggered $chan is invalid since timers are not inherently associated with a specific channel. $network still returns a value because online timers are associated with the connection from which the timer command was first called.

If you want to use the channel from within the _test alias you should pass it as a parameter.


Spelling mistakes, grammatical errors, and stupid comments are intentional.
Joined: Dec 2002
Posts: 2,031
R
Hoopy frood
Offline
Hoopy frood
R
Joined: Dec 2002
Posts: 2,031

I think in this case I would pass $chan to the alias...

Code:

on *:TEXT:!start:#test: _start
on *:INPUT:#test: if ($1 == !start) _start

alias _start {
  echo -a I can see both $network and $chan here
  .timer 1 5 _test $chan
}

alias _test { echo -a but I cant see both $network and $1 here }



Joined: Dec 2002
Posts: 2,962
S
Hoopy frood
Offline
Hoopy frood
S
Joined: Dec 2002
Posts: 2,962
Quote:
Change the $chan in the second alias to $active

That's no good. There's no reason to believe the channel the event was triggered from will be the active channel when the timer triggers.


Spelling mistakes, grammatical errors, and stupid comments are intentional.
Joined: Jul 2007
Posts: 1,129
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
But it works.

Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
The $chan identifier can be accessed within the events (the input or text message occur within a channel) and the alias started out of the event.
Now the timer you start in the alias will execute "outside of" the event definition and it doesn't carry all the identifier values along.
$network works for you because you started an online timer (no -o switch) and every online timer is associated with the respective server connection it was started at.

In your case it doesn't seem useful to store the identifier values somewhere else. Instead, you might pass the required values to the alias and timer.
In the example below both $chan and $network are passed to the alias, and from within the alias to the timer. Passing to the alias is not needed (it executes within the event), passing to the timer is needed.
Code:
; pass network and chan to the _start alias
on *:TEXT:!start:#test: _start $network $chan 
on *:INPUT:#test: if ($1 == !start) _start $network $chan

alias _start {
  echo -a I can see both network $1 and chan $2 here
   ; forward $1=network and $2=chan to the timer as well
  .timer 1 5 _test $1 $2
}

alias _test { echo -a And I can see both network $1 and chan $2 here as well }
...I hope you get the general idea.

But there's an important issue with this method you have to consider: Everything in the command part of a timer will be evaluated. In the code above, in the _start alias, $1 and $2 are filled with <networkname> and <channelname> - and these values will be evaluated in the timer: for example a channel name "#$me" will be evaluated to your nickname.
A "safe" alias is a good method to prevent this evaluation. The secured code would look like:
Code:
on *:TEXT:!start:#: _start $network $chan 
on *:INPUT:#: if ($1 == !start) _start $network $chan

alias _start {
  echo -a I can see both network $1 and chan $2 here
  .timer 1 5 _test $safe($1 $2)
}

alias _test { echo -a And I can see both network $1 and chan $2 here as well }

; keep spacing in this alias as it is!
alias safe { return $!decode( $encode($1,m) ,m) }


__
Edit: Ouch I'm late with this reply... laugh

Joined: Feb 2005
Posts: 342
R
Fjord artisan
Offline
Fjord artisan
R
Joined: Feb 2005
Posts: 342
Umn, if by works you mean "lol it echos your active channel" then yes, you're absolutely right.

Otherwise no, you're entirely wrong. It seems to me this person wants to tie the timer to the channel. In which case said person should be passing along the channel name in the timer as mentioned by someone else.

alias _test { var %chan = $1 | echo -a Chan: %chan $+ , Network: $network }

.timer 1 10 _test $!( $chan ,0)



(Note, I use $!( $chan ,0) there, because "#" is in fact a valid channel, so if the channel is "#" then the timer will attempt to evaluate it, and it'll be null because mIRC evaluates # as $chan.)

Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
The fact it's working in a test run doesn't indicate it's a proper method (It works as long as you don't change the target in these 5 seconds, nothing one may expect in a real chat situation). Likewise some insecure code: the fact it didn't exploit you in a test run won't make it secure.

Joined: Mar 2009
Posts: 2
W
Bowl of petunias
OP Offline
Bowl of petunias
W
Joined: Mar 2009
Posts: 2
Thanks guys, this cleared some stuff up for me.

Someone on irc told me that by the time the timer fired the command, the scope for $chan was lost. This makes absolute sense to me, but I'm just curious if there is a way to refocus $chan to be the one used when _start was called... I was reading the help files and I saw stuff about $cid and /scid to force a command to work on a specific channel id. Would it be possible to reinitialize $chan using a $cid? That way, I could just do something like this:

Code:
on *:TEXT:!start:#test: _start
on *:INPUT:#test: if ($1 == !start) _start

alias _start { 
  echo -a cid is: $cid & chan is: $chan
  .timer 1 5 _test $cid
}
alias _test {
  /scid $1  
  ..fix $chan.. 
  echo -a cid is: $cid & chan is: $chan 
}



The structure of my code actually goes from _start to _test1 to _test2 and possibly _test3, all requiring access to $chan. I'd hate to have to add parameters to pass $network and $chan to each of these, down the line..

Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
$cid refers to the connection ID of the current script. Connection IDs are unique numbers assigned to every status window (and all the dependend windows like channels).
A timer (if set as default online timer) is associated with a network and a thereby with some connection ID. But the timer is not associated with a specific window (e.g. a channel). Cid's won't help you here.

You inevitably have to tell the command that was triggered by a timer about the channel name on your own. The most easy method is given above: pass the channel name as a parameter.

Other methods may be:
- named timers and you parse the timer name $ctimer, for examplke with token identifiers
- data (like a channel name) is stored separately, e.g. in hash tables or variables (example: %start.channel). BUT: you cannot use a static reference if your script shall work simultaneously for different channels/networks. You'd have to tell the command where to look at in the dataset (example: %start.channel.1 or %start.channel.2 ?), and thus it's inevitable to pass at least an "index number" or so...

Joined: Jan 2007
Posts: 1,156
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Jan 2007
Posts: 1,156
Originally Posted By: WazzUp9918

Code:
on *:TEXT:!start:#test: _start
on *:INPUT:#test: if ($1 == !start) _start

alias _start { 
  echo -a cid is: $cid & chan is: $chan
  .timer 1 5 _test $cid
}
alias _test {
  /scid $1  
  ..fix $chan.. 
  echo -a cid is: $cid & chan is: $chan 
}

The structure of my code actually goes from _start to _test1 to _test2 and possibly _test3, all requiring access to $chan. I'd hate to have to add parameters to pass $network and $chan to each of these, down the line..


Why would you hate to do that? That is the solution. You have to supply parameters to a method just like you do to an alias.


Link Copied to Clipboard