;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WHOWASEXEC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;info: ; ; by wiebe @ QuakeNet ; version 1.0 (written and tested on mIRC 6.14) ; ; last edit: Tue Apr 06 2004 ; ; ;What does this script do? ; ; this script retrieves information from a whowas request ; and passes this on to the specified alias (callback) ; ; /whowasexec [-c] [params..] ; ; the following info is send to the specified alias: ; in the example above, is 'msg' the alias, '#channel' is the params part. ; numeric is the raw numeric the server sends, like 311 ; ; you can use multiple nicks seperated with a , ; like /whowasexec nick1,nick2,nick3,nickN [params..] ; ; the -c switch can be used to clear the queue ; like /whowasexec -c ; ; the script uses a queue, multiple requests are pushed together to the server ; like 'whowas ,,,' ; ; WARNING: DO NOT USE HALT IN AN ALIAS, USE RETURN! ; halt also halts the calling alias/event, return only stops the current alias ; and gives control back to the calling alias/event ; using halt in alias'es that are called from this script can cause it not to work 100% ; ; ;Examples: ; ; examples are included at the end the script, ; 1) public !whowas ; 2) a channelscan script, does a whowas when a user joins and echo's the channels ; 3) /whowas script ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC.DELAY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whowasexec.delay { ; when you use /whowasexec, it will wait N seconds before doing a /whowas ; this delay can be 0 or 10, whatever works for you ; the script's queue works better if it can send multiple things in a whowas request ; if you are not sure about this, leave it return 1 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC.RESTART ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whowasexec.restart { ; the script has send a /whowas , it will wait N seconds before the next whowas request ; if you are not sure about this, leave it return 1 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC.MAXLITEMS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whowasexec.maxitems { ; script does not whowas more then N parts at once ; /whowas ; if you are not sure about this, leave it return 50 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC.MAXLEN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whowasexec.maxlen { ; max length of the /whowas request ; a too long line may cause the server to ignore the command ; 300 should be a good default number ; the script does /whowas never longer then N chars ; if you are not sure about this, leave it return 300 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC.RAW ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whowasexec.raw { ; set this to 1 if you want the script to pass on the raw format of the raw ; the : that marks the last parameter will be included that way ; if you are not sure about this, leave it return 1 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC.RAWS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whowasexec.raws { ; set here what raws numerics are in whowas and what raws you want to get returned ; if you are not sure about this, leave it ; 314 me nick user host * :info ; 369 me request :End of WHOWAS ; 406 me nick :There was no such nickname ; 431 me WHOWAS :No nickname given ; 312 me nick server :time ; 301 me nick :away return 314 369 406 431 312 301 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; stop here, only change stuff if you know what you are doing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; /whowasexec [-c] [params..] alias whowasexec { ; we are connected if ($status == connected) { ; '$1' is '-c' if ($1 == -c) { ; clear the queue $whowasexec.queue($+(whowas.exec.queue.,$cid)).clear } ; do not clear the queue else { ; we got at least 2 parameters, else return if ($0 <= 1) { return } ; set a var var %x = $numtok($1,44) ; loop as long as '%x' is greater then 0 while (%x) { ; add queue '$whowasexec.lower($gettok($1,%x,44))' to the queue ; see 'whowasexec.lower' alias whowasexec.queue $+(whowas.exec.queue.,$cid) $whowasexec.lower($gettok($1,%x,44)) ; check if '$whowasexec.lower($gettok($1,%x,44)) $2-' is not already in the hash table if (!$hfind($+(whowas.exec.queue.,$cid,.item),$whowasexec.lower($gettok($1,%x,44)) $2-,0).data) { ; increase item 'last' in the hash table hinc -m $+(whowas.exec.queue.,$cid,.item) last ; add an item with the value 'last' has with value '$gettok($1,%x,44) $2-' hadd -m $+(whowas.exec.queue.,$cid,.item) $hget($+(whowas.exec.queue.,$cid,.item),last) $whowasexec.lower($gettok($1,%x,44)) $2- } ; decrease '%x' and go on to the next nick dec %x } ; check if the timer does not already run if (!$timer($+($cid,.whowasexec))) { ; start a timer .timer $+ $cid $+ .whowasexec 1 $$whowasexec.delay whowasexec.dump } } } } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC.DUMP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whowasexec.dump { ; part for normal whowas ; set a var var %whowas ; loop as long as there are items in the queue and length of '%whowas' is smaller or equal to the value defined above, number of nicks is lower then defined above while ($whowasexec.queue($+(whowas.exec.queue.,$cid)).size > 0) && ($len(%whowas) <= $$whowasexec.maxlen) && ($numtok(%whowas,44) < $$whowasexec.maxitems) { ; set the next item var %next = $whowasexec.queue($+(whowas.exec.queue.,$cid)).next ; check if '%next' is in the hash table, if it is not do not add it if ($hfind($+(whowas.exec.queue.,$cid,.item),%next *,0,w).data) { ; add it to '%whowas' if it is not already in there var %whowas = $addtok(%whowas,%next,44) } } ; '%whowas' contains something if (%whowas) { ; enable the '#whowasexec' group .enable #whowasexec ; send whowas .quote WHOWAS %whowas } ; there are items left in the queue if ($whowasexec.queue($+(whowas.exec.queue.,$cid)).size > 0) { ; start a timer to start this alias again .timer $+ $cid $+ .whowasexec 1 $$whowasexec.restart whowasexec.dump } } ; start of '#whowasexec' group ; turned off by default #whowasexec off ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RAW * ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; raw *:*:{ ; check if '$numeric' is in the setings above if ($istok($whowasexec.raws,$numeric,32)) && ($numeric != 369) { ; part for 'nick' ; check that nick '$2' is in the hash table if ($hfind($+(whowas.exec.queue.,$cid,.item),$whowasexec.lower($2) *,0,w).data) { ; set a var var %x = $hfind($+(whowas.exec.queue.,$cid,.item),$whowasexec.lower($2) *,0,w).data ; loop as long as '%x' is greater then 0 while (%x) { ; run the alias that is in the hash table and pass '$numeric $2-' on to it $gettok($hget($+(whowas.exec.queue.,$cid,.item),$hfind($+(whowas.exec.queue.,$cid,.item),$whowasexec.lower($2) *,%x,w).data),2-,32) $numeric $iif($whowasexec.raw == 1,$gettok($rawmsg,4-,32),$2-) ; decrease '%x' and go on to the next match dec %x } ; stop mirc from showing this raw haltdef } ; part for 'nick' with wildcards ; check if is in the hash table elseif ($hfind($+(whowas.exec.queue.,$cid,.item),$whowasexec.lower($2) *,0,wW).data) { ; set a var var %x = $hfind($+(whowas.exec.queue.,$cid,.item),$whowasexec.lower($2) *,0,wW).data ; loop as long as '%x' is greater then 0 while (%x) { ; run the alias that is in the hash table and pass '$numeric $2-' on to it $gettok($hget($+(whowas.exec.queue.,$cid,.item),$hfind($+(whowas.exec.queue.,$cid,.item),$whowasexec.lower($2) *,%x,wW).data),2-,32) $numeric $iif($whowasexec.raw == 1,$gettok($rawmsg,4-,32),$2-) ; decrease '%x' and go on to the next match dec %x } } ; stop mirc from showing this raw haltdef } ; '$numeric' is 369, so this is end of /whowas list. if ($numeric == 369) { ; check if the hash table exists if ($hget($+(whowas.exec.queue.,$cid,.item))) { ; set a var var %x = $numtok($2,44) ; loop through the things in '$2' that are seperated by a , while ($gettok($2,%x,44)) { ; set a var with number of matches var %y = $hfind($+(whowas.exec.queue.,$cid,.item),$whowasexec.lower($gettok($2,%x,44)) *,0,w).data ; while '%y' greater is then 0 while (%y) { ; if '369' is set in the raws above if ($istok($whowasexec.raws,369,32)) { ; run the alias that is in the hash table and pass '$numeric $gettok($2,%x,44) $3-' on to it $gettok($hget($+(whowas.exec.queue.,$cid,.item),$hfind($+(whowas.exec.queue.,$cid,.item),$whowasexec.lower($gettok($2,%x,44)) *,%y,w).data),2-,32) $numeric $gettok($2,%x,44) $iif($whowasexec.raw == 1,$gettok($rawmsg,5-,32),$3-) } ; delete the item from the hash table hdel $+(whowas.exec.queue.,$cid,.item) $hfind($+(whowas.exec.queue.,$cid,.item),$whowasexec.lower($gettok($2,%x,44)) *,%y,w).data ; descrease '%y' go on to the next match dec %y } ; decrease '%x' go on to the next nick dec %x } ; stop mirc from showing this raw haltdef ; disable the '#whowasexec' group whowasexec.disable } } } ; end of '#whowasexec' group #whowasexec end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC.LOWER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $whowasexec.lower(nick) alias -l whowasexec.lower { ; on IRC these chars are upper(lower) case of eachother: { = [, } = ], | = \, ~ = ^ ; so here we replace them to make sure we compare the right things right return $replace($1,$chr(123),$chr(91),$chr(125),$chr(93),$chr(124),$chr(92),$chr(126),$chr(94)) } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC.DISABLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; this alias will only disable the group '#whowasexec' if it is nolonger needed (checks all connections) alias -l whowasexec.disable { ; set a var var %x = 1 ; loop through all connection id's while (%x <= $scid(0)) { ; there is 1 item in the 'item' queue if ($hget($+(whowas.exec.queue.,$scid(%x),.item),0).item == 1) { ; free the hash table hfree $+(whowas.exec.queue.,$scid(%x),.item) } ; more then 1 item in the 'item' queue elseif ($hget($+(whowas.exec.queue.,$scid(%x),.item),0).item > 1) { ; stop return } ; increase '%x' and go on to the next connection id inc %x } ; disable the '#whowasexec' group .disable #whowasexec } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOWASEXEC.QUEUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $1 = table, $2 = nick alias whowasexec.queue { ; there is a 2nd parameter and nick '$2' is not already in the queue (and not in the .remote queue) if ($2 != $null) && (!$hfind($1,$2).data) && (!$hfind($+($1,.remote),$2).data) { ; increase item 'last' hinc -m $1 last ; add nick '$2' to the hashtable with item name that 'last' has hadd -m $1 $hget($1,last) $2 } ; called as identifier ($alias) and propertie is next ($alias().next) and hash table '$1' exists elseif ($isid) && ($prop == next) && ($hget($1)) { ; increase item 'first' hinc -m $1 first ; 'first' is smaller or equal to 'last' if ($hget($1,first) <= $hget($1,last)) { ; store next item in var '%next' var %next = $hget($1,$hget($1,first)) ; delete this item from the hashtable hdel $1 $hget($1,first) ; this is the last item if ($hget($1,first) >= $hget($1,last)) { ; free the hash table hfree $1 } ; return '%next' return %next } } ; called as identifier ($alias) and propertie is size ($alias().size) elseif ($isid) && ($prop == size) { ; decrease number of items with 1, (1 item in queue, and last is there) return $iif($calc($hget($1,0).item -1) >= 0,$ifmatch,0) } ; called as identifier ($alias) and propertie is clear ($alias().clear) elseif ($isid) && ($prop == clear) { ; free hashtables that match $1 hfree -w $1 } } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DISCONNECT EVENT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; on *:disconnect: { ; check if the 'item' hash table exist if ($hget($+(whowas.exec.queue.,$cid,.item))) { ; free the hash table hfree $+(whowas.exec.queue.,$cid,.item) } ; clear the queue $whowasexec.queue($+(whowas.exec.queue.,$cid)).clear ; disable the '#whowasexec' group whowasexec.disable } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; EXAMPLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; start of group whowasexec.example ; change 'off' to 'on' or write '/enable #whowasexec.example' to set these examples on #whowasexec.example on ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; EXAMPLE SCRIPT 1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;/whowas [0] alias whowas { if ($2) { whowasexec -r $2 whowascallback } else { whowasexec $$1 whowascallback } } alias whowascallback { ; 314 me nick user host * :info ; 369 me request :End of WHOWAS ; 406 me nick :There was no such nickname ; 431 me WHOWAS :No nickname given ; 312 me nick server :time ; 301 me nick :away if ($1 == 301) { echo $color(whois) -ai2 $2 away $3- } if ($1 == 314) { echo $color(whois) -ai2 $2 was $3- } if ($1 == 369) { echo $color(whois) -ai2 $2- } if ($1 == 312) { echo $color(whois) -ai2 $2 using $3- } if ($1 == 406) { echo $color(whois) -ai2 $2- } } ; whowasexec.example group end #whowasexec.example end