|
Joined: Mar 2007
Posts: 139
Vogon poet
|
OP
Vogon poet
Joined: Mar 2007
Posts: 139 |
greetings, if anyone has sometime to rewrite this little snippet it would be appreciated as it seems really slow and i feel it could be done alot better. alias clonescan {
if ($ial == $false) .ial on
var %i 1,%chan $1
if (!$window($+(@clones,.,$network,.,%chan))) { window -Czd $+(@clones,.,$network,.,%chan) 100 50 690 460 | titlebar $+(@clones,.,$network,.,%chan) Clones list for $+($network,:) $nick(%chan,0) users currently on %chan | font $+(@clones,.,$network,.,%chan)) 12 arial bold }
if (%chan !ischan) { aline -p $+(@clones,.,$network,.,%chan) 4ERROR no such channel $iif(%chan,as %chan) | return }
while (%i <= $nick(%chan,0)) {
if ($ialchan($address($nick(%chan,%i),2),%chan,0) > 1) && ($address($nick(%chan,%i),2) !isin %addr) {
var %addr = %addr $address($nick(%chan,%i),2)
aline -p 12 $+(@clones,.,$network,.,%chan) $timestamp $chr(42) Found ( $+ $ialchan($address($nick(%chan,%i),2),%chan,0) $+ ) Clones in $+($chr(40),%chan,$chr(41)) from ( $+ $gettok($address($nick(%chan,%i),2),2,64) $+ )
var %cnt 1
while (%cnt <= $ialchan($address($nick(%chan,%i),2),%chan,0)) {
aline -p $+(@clones,.,$network,.,%chan) $timestamp $chr(42) $+(%cnt,.) $ialchan($address($nick(%chan,%i),2),%chan,%cnt).nick
inc %cnt
}
aline -p $+(@clones,.,$network,.,%chan) -
}
inc %i
}
if (!%addr) { aline $+(@clones,.,$network,.,%chan) $timestamp 4,1No clones found on %chan }
}
|
|
|
|
Joined: Jul 2006
Posts: 4,153
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,153 |
You use a while loop to check each address on the channel, so if you have 300 nick on a channel, it's normal that it take time.
You should use the /names #channel to get each nick
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Dec 2002
Posts: 503
Fjord artisan
|
Fjord artisan
Joined: Dec 2002
Posts: 503 |
alias clonescan {
if ($ial == $false) {
; note: if the IAL isn't on before this, ouch! Nothing will be in the IAL!
.ial on
return
}
var %i = 1, %chan = $1, %win = $+(@clones,.,$network,.,%chan), %addr
if (!$window(%win)) {
window -Czd %win 100 50 690 460
titlebar %win Clones list for $+($network,:) $nick(%chan,0) users currently on %chan
font %win 12 arial bold
}
if (%chan !ischan) {
aline -p %win 4ERROR no such channel $iif(%chan,as %chan)
return
}
while ($nick(%chan, %i)) {
var %smask = $address($v1,%i)
if ($ialchan(%smask,%chan,0) > 1) && (%smask !isin %addr) {
%addr = %addr $address($nick(%chan,%i),2)
aline -p 12 %win $timestamp $chr(42) Found ( $+ $ialchan(%smask,%chan,0) $+ ) Clones in $+($chr(40),%chan,$chr(41)) from ( $+ $gettok(%smask,2,64) $+ )
var %cnt = 1
while ($ialchan(%smask,%chan,%cnt)) {
aline -p %win $timestamp $chr(42) $+(%cnt,.) $gettok($v1, 1, 33)
inc %cnt
}
aline -p %win -
}
inc %i
}
if (!%addr) {
aline %win $timestamp 4,1No clones found on %chan
}
else {
aline %win $timestamp 4,1Scan on %chan complete!
}
} So, why would this be faster? A few reasons: Every time through the loop, you were re-evaluating the window name a minimum of 4 times. 300 people in a channel means a minimum of 1200 evaluations of that one string, which isn't changing. Slow down. With that in mind, we do the same thing with the $address($nick(%chan,%i), 2). This is an IAL lookup to begin with, so instead of doing a few as possible lookups, you were doing double, which in a single pass would be something like 11 lookups. This cuts it in half to 3-4. The while loops were changed as well, so that the full count isn't required for every-iteration-of-the-loop. Anyway, my tests of the above code in a 370 user channel takes about a second on my underclocked P4.
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,559 |
Here's a quite similar scanner I made some time ago; for this post I did a bad translation of the output, added some comments, removed my own hotlinks, separated the colouring from the theme to variables etc - maybe it's usefull none the less... The uper part is the scanning thingie as you'll see, the lower (messy) part is about output formatting :X My own approach is far from being "speed optimized", but looking at yours some thougts: - a-lining is faster if the window is hidden - "while (%i <= $nick(%chan,0))" why not "while ($nick,%chan,%i)"? Then you could use $ifmatch / $v1 to refer to the matching nickname of that loop directly - you are refering to "$address($nick(%chan,%i),2)" many times, you could set this to a var, do the same with the window name ; clonescan2 <#channel>
alias clonescan2 {
var %start = $ticks, %nicks = $ialchan(*,$1,0), %nick.num = 1
var %prefixreg = $+(/,$chr(40),[,$prefix,],$chr(41),/g), %clones, %lines, %groups
; • here you can modify the display colours •
var %c1 = 07, %c2 = 11, %c3 = 10, %c4 = 14
; ••• cycle all nicks of that channel •••
while ($nick($1,%nick.num)) {
var %host = $mask($ialchan($v1,$1,1),2), %matches = $ialchan(%host,$1,0)
; • clones found (host has more than 1 nicks on chan) •
if (%matches > 1) {
; • add the current nick to the variable of nicks for that host, inc count of total clones •
var %clones. [ $+ [ %host ] ] $($+(%,clones.,%host),2) $nick($1,%nick.num).pnick
inc %clones
; • if all clones for a host had been found •
if ($numtok($($+(%,clones.,%host),2),32) == %matches) {
; • prepare the lines for the output (stored as variables) •
var %makelines = $ceil($calc(%matches /3)), %nr = 1
while (%nr <= %makelines) {
inc %lines
; • in this messy line, the values are coloured etc •
var %line. [ $+ [ %lines ] ] $chr(9) $iif((%nr == 1),$+ %c3 $+ $numtok($($+(%,clones.,%host),2),32)) $chr(9) $iif((%nr == 1),$gettok(%host,2,64)) $chr(9) %c3 $+ $&
$gettok($replace($regsubex($($+(%,clones.,%host),2),%prefixreg,$+(%c1,\t,%c3)),$chr(32),$+($chr(44),$chr(32)) ),$+($calc((%nr -1) *3 +1),-,$calc(%nr *3)),32)
inc %nr
}
inc %groups
inc %lines
var %line. [ $+ [ %lines ] ] $chr(9) %c4 $+ $str(-,163)
}
}
inc %nick.num
}
; ••• output •••
; • create window (dynamic size) •
var %wind = $+(@,Clonescan,$chr(160),$1)
window -hk0z -t1,4,20 %wind -1 -1 900 $round($calc(18 * $iif((%lines),%lines,0) +128),0) Arial 15
; • title •
aline %wind $+($chr(9) %c3,$str(•,40) $str($chr(160),3) %c2,Clonescan %c3,at %c2,$1 %c3,$str($chr(160),3) $str(•,40))
aline %wind $chr(9)
; • output "total" / "no clones" / scan time / time and date •
aline %wind $chr(9) $&
$iif((%clones),$+(%c3,Total: $chr(9) $chr(91),%c2,%clones,%c3,$chr(93)),$chr(9) %c3 $+ No) Clones $+(%c3,of $chr(91),%c2,%nicks,%c3,$chr(93) Users) $iif((%clones),$+(in $chr(91),%c2,%groups,%c3,$chr(93)) $iif((%groups == 1),Group.,Groups.),found.) $&
$chr(9) %c4 $+ (Scan time: $round($calc(($ticks - %start) /1000),2) Seconds) %c3 $+ $+([,$date(dd.mm.yyyy),$chr(44) $time,])
aline %wind $chr(160)
; • output of the clones list •
if (%clones) {
aline %wind %c2 $+ $chr(2) $chr(9) Clones $chr(9) Host $chr(9) Nicks
var %num = 1
while ($($+(%,line.,$calc(%num +1)),2)) {
aline %wind $($+(%,line.,%num),2)
inc %num
}
}
; • end of output, show window •
aline %wind $chr(9) %c4 $+ $str(-,163)
window -ra %wind
}
|
|
|
|
Joined: Dec 2002
Posts: 503
Fjord artisan
|
Fjord artisan
Joined: Dec 2002
Posts: 503 |
*chuckles* same thoughts ;P
|
|
|
|
Joined: Jul 2006
Posts: 4,153
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,153 |
I think the best method is the /names, because you only need one while, using $*... Here is my method, i use bekar's code : alias clonescan {
if ($ial == $false) {
.ial on
return
}
var %chan = $1, %win = $+(@clones,.,$network,.,%chan)
if (!$window(%win)) {
window -Czd %win 100 50 690 460
titlebar %win Clones list for $+($network,:) $nick(%chan,0) users currently on %chan
font %win 12 arial bold
}
if (%chan !ischan) {
aline -p %win 4ERROR no such channel $iif(%chan,as %chan)
return
}
set -u2 %names.win %win
names %chan
}
raw 353:*:if (%names.win) { var %chan $3 | tokenize 32 $remove($4-,@,%,+) | haltdef | loopadd %chan $* }
raw 366:*:{
if (%names.win) {
haltdef
aline %names.win $timestamp 4,1 $+ $iif(%names.addr,Scan on $2 complete!,No clones found on $2)
unset %names.*
}
}
alias loopadd {
var %smask $address($2,2) ,%c $1
if ($ialchan(%smask,%c,0) > 1) && (%smask !isin %names.addr) {
set %names.addr %names.addr $v1
aline -p 12 %names.win $timestamp $chr(42) Found ( $+ $ialchan(%smask,$1,0) $+ ) Clones in $+($chr(40),%c,$chr(41)) from ( $+ $gettok(%smask,2,64) $+ )
var %cnt 1
while ($ialchan(%smask,%c,%cnt)) {
aline -p %names.win $timestamp $chr(42) $+(%cnt,.) $gettok($v1,1,33)
inc %cnt
}
aline -p %names.win -
}
} On a big channel (300 person...) this method is faster than a while and not freeze mirc.
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Dec 2002
Posts: 503
Fjord artisan
|
Fjord artisan
Joined: Dec 2002
Posts: 503 |
the hell? IRCHighway #lurk: 1358 members. 3-4 seconds.. Just how big a channel are you wanting to use it on? In any case, waiting for a REPL_NAMES makes it go 'slower'..
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,559 |
The only advantage of "names" that I see is the de-freeze effect as you retrieve the nicks in packages, but it's not affecting the amount of processing (?) 1) loop all users (ialchan or names) and check their site for clones 2) if a site is present more than once (clones),add the nick to a group of that site a) process the rest of the group instantly and skip this site later or b) process the nicks linear and add all other matches for a site to it's group 3) output the cloning nicks in groups
|
|
|
|
Joined: Jul 2006
Posts: 4,153
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,153 |
Just how big a channel are you wanting to use it on? In any case, waiting for a REPL_NAMES makes it go 'slower'.. ;\) You're right, the worst is that i've already make some bench in the past and already seen that /names is slower than the loop, it's certainly the word *while* that remind me "no, it's slow!! " Anyway thx for clarification.
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Mar 2007
Posts: 139
Vogon poet
|
OP
Vogon poet
Joined: Mar 2007
Posts: 139 |
Hi Bekar thanks for that, small problem is that at times it can pick up the same clones twice, anyway you can fix that please.
|
|
|
|
Joined: Jul 2006
Posts: 4,153
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,153 |
I think Bekar made some typo when he re-wrote your code. Replace the while by this one while ($nick(%chan, %i)) {
var %smask = $address($v1,2)
if ($ialchan(%smask,%chan,0) > 1) && (%smask !isin %addr) {
%addr = %addr %smask
aline -p 12 %win $timestamp $chr(42) Found ( $+ $ialchan(%smask,%chan,0) $+ ) Clones in $+($chr(40),%chan,$chr(41)) from ( $+ $gettok(%smask,2,64) $+ )
var %cnt = 1
while ($ialchan(%smask,%chan,%cnt)) {
aline -p %win $timestamp $chr(42) $+(%cnt,.) $gettok($v1, 1, 33)
inc %cnt
}
aline -p %win -
}
inc %i
}
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Mar 2007
Posts: 139
Vogon poet
|
OP
Vogon poet
Joined: Mar 2007
Posts: 139 |
Thnaks Wims,
In really big channles i get /set: line too long (line 681, script1.mrc) because it cant set such a long variable, is there any way round this?
|
|
|
|
Joined: Jul 2006
Posts: 4,153
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,153 |
Yes, use hash table instead of variable : alias clonescan {
if ($ial == $false) {
; note: if the IAL isn't on before this, ouch! Nothing will be in the IAL!
.ial on
return
}
var %i = 1, %chan = $1, %win = $+(@clones,.,$network,.,%chan), %addr
if (!$window(%win)) {
window -Czd %win 100 50 690 460
titlebar %win Clones list for $+($network,:) $nick(%chan,0) users currently on %chan
font %win 12 arial bold
}
if (%chan !ischan) {
aline -p %win 4ERROR no such channel $iif(%chan,as %chan)
return
}
while ($nick(%chan, %i)) {
var %smask = $address($v1,2)
if ($ialchan(%smask,%chan,0) > 1) && (!$hget(addr,%smask)) {
hadd -m addr %smask 1
aline -p 12 %win $timestamp $chr(42) Found ( $+ $ialchan(%smask,%chan,0) $+ ) Clones in $+($chr(40),%chan,$chr(41)) from ( $+ $gettok(%smask,2,64) $+ )
var %cnt = 1
while ($ialchan(%smask,%chan,%cnt)) {
aline -p %win $timestamp $chr(42) $+(%cnt,.) $gettok($v1, 1, 33)
inc %cnt
}
aline -p %win -
}
inc %i
}
if (!$hget(addr)) {
aline %win $timestamp 4,1No clones found on %chan
}
else {
aline %win $timestamp 4,1Scan on %chan complete!
hfree addr
}
} Edit : correct a mistake.
Last edited by Wims; 22/11/07 12:06 PM.
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
Joined: Feb 2003
Posts: 3,432
Hoopy frood
|
Hoopy frood
Joined: Feb 2003
Posts: 3,432 |
I noticed the code in here, and i tested it, working just fine, but i never seen a window using %win = $+(@clones,.,$network,.,%chan), %addr to be created, and i was fooling around a bit with the code, and i was wondering, any way to add a @menu to a window created that way? i tested to save $+(@clones,.,$network,.,%chan), %addr to a %var, then use menu %var .. and no luck, the %var is saved the same way the window is created, how come the menu dosent work for it?
if ($me != tired) { return } | else { echo -a Get a pot of coffee now $+($me,.) }
|
|
|
|
Joined: Nov 2006
Posts: 1,559
Hoopy frood
|
Hoopy frood
Joined: Nov 2006
Posts: 1,559 |
You can use wildcards and parse the window name //window $+(@clones.,$network,.,$chan(1)) menu @clones.* {
$iif(($gettok($active,2,46) == $network),stuff with chan $gettok($active,3-,46)) : echo $active works
} EDIT In addition, if it's no list window ($sline), you could use a hotlink event to store the right-clicked line ("if ($mouse.key && 16) ... stuff with $hotline") temporarily (e.g. to a hash that will be destroyed if the @window is closed),and use this data in the menu definition. (Quite a hack, but it works well for me)
Last edited by Horstl; 22/11/07 02:15 PM.
|
|
|
|
Joined: Feb 2003
Posts: 3,432
Hoopy frood
|
Hoopy frood
Joined: Feb 2003
Posts: 3,432 |
ty, got it to work..
if ($me != tired) { return } | else { echo -a Get a pot of coffee now $+($me,.) }
|
|
|
|
|