mIRC Home    About    Download    Register    News    Help

Print Thread
#205743 30/10/08 07:53 PM
Joined: Feb 2003
Posts: 3,432
S
sparta Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: Feb 2003
Posts: 3,432
I have been asking before what the best way to do a /who in channels without causing to much lag, i got some answers but none of them was any good, the reason for the /who $chan is to gain info about irc-operators and users away on the channel, so how would i do this the best way? cos when i join like 2 or more channels with 60+ users on them, then i get a huge lag, so how can i avoid this lag?


if ($me != tired) { return } | else { echo -a Get a pot of coffee now $+($me,.) }
Joined: Jul 2007
Posts: 1,129
T
Hoopy frood
Offline
Hoopy frood
T
Joined: Jul 2007
Posts: 1,129
Code:
on *:JOIN:#: {
  if ($nick == $me) .set -su120 %WhoChan. $+ $chan $true
  else who $nick
}
raw 366:*: {
  var %chan = $2
  if ($eval(% $+ WhoChan. $+ %chan,2)) {
    unset $eval(% $+ WhoChan. $+ %chan,1)
    var %i = 1,  %nick
    while ($nick(%chan,%i)) {
      %nick = $v1
      if (%nick != $me) .timer -m 1 $calc(%i * 1500) who %nick
      inc %i
      haltdef
    }
  }
}


I have the above script from awhile back, and I added a timer to who the channels, so that it won't cause unnecessary lag due to a flood. I thought it'd be referable to you to look at.

Last edited by Tomao; 30/10/08 10:07 PM.
Joined: Jan 2007
Posts: 1,156
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Jan 2007
Posts: 1,156
If you are flooding the server which results in a disconnection then you need to work with timers. Every server is different. It is up the server admin's settings that determines what the server constitutes as flooding and what it's solution for it is.

This is why, as a mIRC script developer, we have to work with timers to slow down multiple requests so that we dont flood out.

Joined: Feb 2003
Posts: 3,432
S
sparta Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: Feb 2003
Posts: 3,432
I testing the code now, but can someone point me to a network with half operators? smile


if ($me != tired) { return } | else { echo -a Get a pot of coffee now $+($me,.) }
Tomao #205766 31/10/08 01:22 PM
Joined: Feb 2003
Posts: 3,432
S
sparta Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: Feb 2003
Posts: 3,432
I tested the code, and have been editing it a bit, but still it's slow, if i join a channel with 100+ users, then it takes for ever before i can do something on the channel, like DCC chat a bot or gain access to the channel central, can this be done in a bether way? mirc it self store all nick's in the ial, but it arent as slow and wont be lagged, can that be used in some way? if it can, then please explain how.


if ($me != tired) { return } | else { echo -a Get a pot of coffee now $+($me,.) }
Joined: Mar 2007
Posts: 218
V
Fjord artisan
Offline
Fjord artisan
V
Joined: Mar 2007
Posts: 218
I'm not sure why you get so much lag on mIRC from your /who.

You're not on a significant amount of channels or networks.
I'm on 7 channels on EFNet, 3 on Undernet, and 2 each on my friends 2 networks.

I always /who when i join so the IAL is up to date.

Code:
       Finished updating /who list for [#channel] 227 entries in [640ms]


^ That was the slowest one, and i never flood off. confused

Joined: Feb 2003
Posts: 3,432
S
sparta Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: Feb 2003
Posts: 3,432
If i join channels with more then 60 users, then i get the lag, and i cant do anything in mirc for 10 sec or sometimes even longer. when i join small channels it's no problem.

;------- Edit

I paste the code here, then you see how mine looks like:
Code:
 ; i using nicklust too, but the coloring of opers/away wont be used untill nicklust = disabled.
on ^*:join:#: {
  if ($nick == $me) {
  if (%nlust == off) { col.nick | .set -su120 %whochan. $+ $chan $true }
 }
}

; grabing the raw events from /who
raw 352:*: {
  if ($me !ison $2) { return }
  if ($6 !ison $2) { return }
  var %a
  if (* isin $7) && ($6 != $me) { %a = $clinecol(io) }
  if (G isin $7) && ($6 != $me) { %a = $clinecol(aw) }
  if %a { cline -l %a $2 $6 }
  haltdef
}
raw 366:*: {
  var %chan = $2
  if ($eval(% $+ WhoChan. $+ %chan,2)) {
    unset $eval(% $+ WhoChan. $+ %chan,1)
    var %i = 1,  %nick
    while ($nick(%chan,%i)) {
      %nick = $v1
      if (%nick != $me) .timer -m 1 $calc(%i * 1500) who %nick
      inc %i
      haltdef
    }
  }
}

Last edited by sparta; 31/10/08 01:54 PM.

if ($me != tired) { return } | else { echo -a Get a pot of coffee now $+($me,.) }
Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
I didn't test this at length, there may be some pitfalls left...it's more some kind of "draft" (and no actual coloring command, some echos to remove).
And maybe the multiserver thingie is a bit overkill at first glance... but I'm sure you'll add one sooner or later laugh

Code:
; you join
on me:*:join:#: { 
  if (%nlust == off) { 
    ; donno what col.nick does :) 
    ; col.nick 
    ; store the joined chan (and cid reference) to a table for 120 secs.
    ; (token separator $chr(9) 'cause it mustn't be part of channel names)
    hadd -smu120 colorchans $+($cid,$chr(9),$chan) joined
  }
}

; end of /names reply
raw 366:*: {
  ; it's one of the chans you joined in the last 120secs
  if ($hget(colorchans,$+($cid,$chr(9),$2)) == joined) { 
    ; mark this chan to be who'd for coloring
    hadd -s colorchans $+($cid,$chr(9),$2) getwho
    ; named timer to trigger the who requests with 5 secs offset, thus
    ; other "end of names" (e.g. multiple joins) may add to the table as well etc.
    .timer.color.getwho -i 1 5 color.getwho
  }
}

; alias to who all the channels marked "getwho" in the table
alias color.getwho {
  ; there's a channel to who in the table
  if ($hfind(colorchans,getwho,1).data) { 
    tokenize 9 $v1
    ; you're still on that cid
    if ($scid($1)) {
      ; and you're still on that chan
      if ($me ison $2) {
        ; var: "this is the chan to parse and haltdef incoming who replies for"
        ; (other who replies pass and remain visible)
        set -e %colorchans.current $+($1,$chr(9),$2)
        ; who the chan (not the nicks one by one)
        ECHO -s whoing chan $2 on cid $1
        scid $1
        .who $2
        scid -r
      }
      ; yo're no longer on that chan: delete item and retrigger the alias
      ; (you might be on other uncolored chans)
      else {
        hdel -s colorchans $+($1,$chr(9),$2)
        .timer -m 1 1 color.getwho
      }
    }
    ; you're no longer on that cid: delete all items of this cid, retrigger the alias
    ; (you might be on other uncolored cids)
    else {
      hdel -sw colorchans $+($1,$chr(9),*)
      .timer -m 1 1 color.getwho
    }
  }
  else { unset %colorchans.current }
}

; who reply
raw 352:*: {
  ; it's the channel you're whoing for coloring
  if ($+($cid,$chr(9),$2) == %colorchans.current) {
    ; it's not your own nick
    if ($6 != $me) {
      if (G isin $7) { ECHO -s color "GONE": nick $6 on chan $2 on cid $cid }
      elseif (* isin $7) { ECHO -s color "IRCOP": nick $6 on chan $2 on cid $cid }
    }
    haltdef
  }
}

; end of who reply
raw 315:*: {
  ; it's the channel you've whod for coloring
  if ($+($cid,$chr(9),$2) == %colorchans.current) {
    ; delete the entry 
    hdel -s colorchans $+($cid,$chr(9),$2)
    ECHO -s finished coloring channel $2 on cid $cid
    ; proceed to next chan-to-who
    color.getwho
    haltdef
  }
}


What it does:
First, it's adding all me-joined chans to a hash table.
On end of /names reply for a chan joined (that is, found in the table), it's marking this chan in the table to "get the wholist for it". All other /names replies pass.
Five seconds after the LAST /names reply (using a named timer) it's starting to who the first (not in order, it's a hash table) marked chan. I used a 5sec timer, as there may be multiple /names replies if you join multiple chans at once, or even multiple scons.
The currently "who'd" chan is always marked (using a variable), and incoming /who replies are checked against this variable: If it's a who reply triggered for coloring purposes, its processed and halted. thus, other /who requests pass. Same goes for "end of who": if it's a channel who'd for coloring, the coloring of this chan was done, thus the entry in the table can be deleted, and the script will now who the next chan in the table (if there is one).

I incorporated 2 of 3 proposes to reduce your lag problem:

1) (Regarding the last script): Who the whole chan instead of timer-whoing each and every nick. This may sound strange, but you end up with less incomming traffic (no "end of who" for every nick). And you're sending only a fraction of requests, compared to nick-based who's. Apart from the traffic thing, a hundred unnamad timers add unnecessarry overhead to mIRC.

2) Trigger the next /who only if the last one has finished. No "hard coded" timers; you script is accommodating itself to the networks response time.

The 3rd suggestion can reduce the required who replies to a fraction and maybe your lag too: use "/who +m Go #" instead of "/who #", that is: who for gone and opered users only. I didn't add it to the code above, 'cause I'm not sure whether all networks support it or not.

In addition, check other scripts parsing raw 366 (end of names), 352 (who reply) and 315 (end of who): are they doing only required things (are they only processing replies called by their respective script)?

Last edited by Horstl; 31/10/08 04:47 PM.
Joined: Feb 2003
Posts: 3,432
S
sparta Offline OP
Hoopy frood
OP Offline
Hoopy frood
S
Joined: Feb 2003
Posts: 3,432
Lo, and thanx for the explanation, the "col.nick" does just what is says, it coloring the nick's. I only grab away users and opers true the raw, the rest i can set due channel status, if ($nick isop $chan) .. =)


if ($me != tired) { return } | else { echo -a Get a pot of coffee now $+($me,.) }

Link Copied to Clipboard