;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; WHOEXEC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;info: ; ; by wiebe @ QuakeNet ; version 1.0 (written and tested on mIRC 6.14) ; ; tested on IRC servers: ; u2.10.11.04 IRCU -> UnderNet ; u2.10.11.04+asuka(1.0.6a) IRCU+ASUKA -> QuakeNet ; ; last edit: Sat Mar 20 2004 ; ; ;What does this script do? ; ; retrieves all possible information from a WHO request ; and sends this to the specified alias, example: ; ; command: /whoexec L msg #channel &all ; ; makes this: ; ; [15:41:14] <@wiebe> * TheLBot 127.0.0.1 lightweight.quakenet.org *.quakenet.org L H*d 3 0 L The lean, mean opping machine. ; ; what happened? ; the script requested all info in a WHO request about L, ; when the info was returned by the server, it was passed on to: ; 'msg #channel &all' ; which resulted in the msg to the channel as shown above ; ; the script uses 'specific who request' or formatflags ; ; ;How to use this script? ; ; /whoexec [-cu] ; ; /whoexec -u ; to update and save the info for $whoexec(nick) identifier ; ; /whoexec -c ; to clear the queue ; ; ; can be a comma seperated list of nicks and/or a channels and may contain wildcards ; the script uses a queue to send as many things as possible in a who request ; however due to the way the who command works, anything containing a wildcard is send alone ; for channels you are not on, the who output is limited, therefor the script sends these requests alone ; note that using who on a large channel while being on it may cause disconnection with error Max sendQ exceeded ; ; ; use &all to get the info from the who request (default) ; you can use anything in this part, only the things mentioned here will be replaced ; the rest is unchanged ; the script replaces so 'test&alltest' will not work, 'test &all test' will ; ; you can get specific parts by using the following: ; ; &c channel last join by the user which does not have set chanmode p/s, returns * for none/hidden ; &u user, returns the user part of the host nick has (nick!user@host) ; &i ip, returns ip (ip can be fake, like when the user has set usermode x) ; &h host, the hostname nick has on IRC (nick!user@host) ; &s server, returns the server nick is using ; &n nick, returns the nick ; &f flags, returns usermodes nick has set ; H (Here) and G (Gone) show the away status, a * means nick is an IRC Operator ; and a @ or + means nick is opped or voiced on channel that is returned with &c (see above) ; &d distance shows how many 'hops' nick is away from you (1 hop is 1 server away) ; &l idle, shows the seconds nick has been idle ; &a account, shows the account nick has, returns 0 for none ; &r realname, returns the realname that nick has ; ; ; $whoexec(nick,flags) ; this will work for users that are in your IAL and the info has been requested ; the script saves the info in a hashtable and adds a mark in the IAL entry for the user with whoexec- ; some parts may not be usefull such as nick, host or username, but other parts are ; some parts may change (account) and other may not (realname) ; this can be usefull as it is not always needed to wait for the server reply ; the script does not update this list by itself ; if no flags are specified, &all is returned ; ; ; 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) an alias to message the info to a channel ; 2) an alias to ban users on auth on QuakeNet ; 3) an alias to ban a user on ip ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.DELAY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whoexec.delay { ; when you use /whoexec, the script will wait N seconds before sending the who ; you can set anything, 0 or greater ; if you are not sure, leave it return 1 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.RESTART ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whoexec.restart { ; if the script send a who request and there are still items left in the queue, ; the script will wait N seconds before sending the next who request ; if you are not sure, leave it return 5 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.MAXITEMS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whoexec.maxitems { ; max number of requests in the /who request ; if you are not sure, leave it return 150 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.MAXL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whoexec.max { ; max number of replies from the WHO request ; nomore then N nicks ; for channel which you are on, counts the number of users on it return 500 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.MAXLEN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whoexec.maxlen { ; max length of the /who request ; a too long line may cause the server to ignore the command ; 300 should be a good default number ; if you are not sure, leave it return 300 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.RAW ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whoexec.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 ; in this case the : in front of the realname part ; if you are not sure, leave it return 0 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.QUERYT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whoexec.queryt { ; what query number to use, range 0-999 ; this takes the right 3 numbers of the hash number of '$cid' ; if you are not sure, leave it return $right($hash($cid,32),3) } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.UPDATE.DELAY ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whoexec.update.delay { ; the script will update the info for $whoexec() identifier every N seconds ; do not set this too low ; only channels where the IAL has been filled are updated ; leave empty to disable return 120 } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; stop here, only change stuff if you know what you are doing ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; /whoexec [params..] ; $whoexec(nick,flags) alias whoexec { ; we are connected if ($status == connected) { ; called as identifier if ($isid) { ; check IAL and hash table if ($ial($1)) && ($hget($+(whoexec.,$cid,.ial),$gettok($wildtok($ial($1).mark,whoexec-*,1,32),2,45))) { ; none of the following '&c &u &i &h &s &n &d &l &a &r &all' are in '$2' if (!$regex($2,\&([cuihsndlar]|all))) { ; add '&all', so by default all info is returned tokenize 32 $1 &all } ; set a var var %info = $hget($+(whoexec.,$cid,.ial),$gettok($wildtok($ial($1).mark,whoexec-*,1,32),2,45)) ; .ctime if ($prop == ctime) { ; return ctime return $gettok(%info,1,32) } ; return the info return $whoexec.replace($gettok(%info,2-6,32) $1 $gettok(%info,7-,32),$2) } } ; not called as identifier else { ; set var var %u = 0 ; switches are used if ($left($1,1) == -) { ; c switch is used if ($1 == -c) { ; clear the queue $whoexec.queue($+(whoexec.queue.,$cid,.*)).clear ; stop return } ; u switch is there elseif (u isin $1) { ; set var var %u = 1 } ; tokenize tokenize 32 $2 -u } ; we got at least 2 parameters, else return if ($0 < 2) { !return } ; none of the following '&c &u &i &h &s &n &d &l &a &r &all' are in '$3-' if (!$regex($3-,\&([cuihsndlar]|all))) && (!%u) { ; add '&all', so by default all info is returned tokenize 32 $1- &all } ; replace some chars in '$1', see in the alias 'whoexec.lower' why this is needed tokenize 32 $whoexec.lower($1) $2- ; set a var var %x = $numtok($1,44) ; loop as long as '%x' is greater then 0, to add all items to the queue while (%x) { ; channel if ($left($gettok($1,%x,44),1) isin $chantypes) { ; on channel if ($me ison $gettok($1,%x,44)) { ; add to chan queue whoexec.queue $+(whoexec.queue.,$cid,.onchan) $gettok($1,%x,44) } ; not on channel else { ; add to chan queue whoexec.queue $+(whoexec.queue.,$cid,.exchan) $gettok($1,%x,44) } } ; wildcard elseif (* isin $gettok($1,%x,44)) || (? isin $gettok($1,%x,44)) { ; add to wild queue whoexec.queue $+(whoexec.queue.,$cid,.wild) $gettok($1,%x,44) } ; nick else { ; add to nick queue whoexec.queue $+(whoexec.queue.,$cid,.nick) $gettok($1,%x,44) } ; check if '$gettok($1,%x,44) $2-' is not already in the hash table if (!$hfind($+(whoexec.queue.,$cid,.item),$gettok($1,%x,44) $2-,0).data) { ; increase item 'last' in the hash table hinc -m $+(whoexec.queue.,$cid,.item) last ; add an item with the value 'last' has with value '$gettok($1,%x,44) $2-' hadd $+(whoexec.queue.,$cid,.item) $hget($+(whoexec.queue.,$cid,.item),last) $gettok($1,%x,44) $2- } ; decrease '%x' go on to the next nick dec %x } ; check if the timer does not already run if (!$timer($+($cid,.whoexec))) { ; start a timer .timer $+ $cid $+ .whoexec 1 $$whoexec.delay whoexec.dump } } } } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.DUMP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias -l whoexec.dump { ; set var var %max = 0, %who ; check size of queue if ($whoexec.queue($+(whoexec.queue.,$cid,.wild)).size > 0) { ; set var var %wild = $whoexec.queue($+(whoexec.queue.,$cid,.wild)).next ; send WHO .quote WHO %wild $+(n%tcuihsnfdlar,$chr(44),$$whoexec.queryt) } ; check size of queue elseif ($whoexec.queue($+(whoexec.queue.,$cid,.exchan)).size > 0) { ; set var var %exchan = $whoexec.queue($+(whoexec.queue.,$cid,.exchan)).next ; not on chan if ($me !ison %exchan) { ; set WHO .quote WHO %exchan $+(n%tcuihsnfdlar,$chr(44),$$whoexec.queryt) } ; on chan else { ; add to other queue whoexec.queue $+(whoexec.queue.,$cid,.onchan) %exchan } } ; check size of queue elseif ($whoexec.queue($+(whoexec.queue.,$cid,.onchan)).size > 0) || ($whoexec.queue($+(whoexec.queue.,$cid,.nick)).size > 0) { ; loop while ($whoexec.queue($+(whoexec.queue.,$cid,.onchan)).size > 0) && (%max < $whoexec.max) && ($numtok(%who,44) < $whoexec.maxitems) { ; set var var %chan = $whoexec.queue($+(whoexec.queue.,$cid,.onchan)).next ; on chan if ($me ison %chan) { ; inc var inc %max $nick(%chan,0) ; inc var inc %maxitems ; set var var %who = $addtok(%who,%chan,44) } ; not on chan else { ; add to queue whoexec.queue $+(whoexec.queue.,$cid,.exchan) %chan } } ; loop while ($whoexec.queue($+(whoexec.queue.,$cid,.nick)).size > 0) && (%max < $whoexec.max) && ($numtok(%who,44) < $whoexec.maxitems) { ; set var var %nick = $whoexec.queue($+(whoexec.queue.,$cid,.nick)).next ; inc var inc %max ; inc var inc %maxitems ; set var var %who = $addtok(%who,%nick,44) } } ; '%who' contains something if (%who) { ; enable the '#whoexec' group .enable #whoexec ; send who .quote WHO %who $+(n%tcuihsnfdlar,$chr(44),$$whoexec.queryt) } ; there are items left in the queue if ($whoexec.queue($+(whoexec.queue.,$cid,.wild)).size > 0) || ($whoexec.queue($+(whoexec.queue.,$cid,.exchan)).size > 0) || ($whoexec.queue($+(whoexec.queue.,$cid,.onchan)).size > 0) || ($whoexec.queue($+(whoexec.queue.,$cid,.nick)).size > 0) { ; start a timer to start this alias again .timer $+ $cid $+ .whoexec 1 $$whoexec.restart whoexec.dump } } ; start of '#whoexec' group ; set off by default #whoexec off ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RAW 354 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; format: 354 : raw 354:& & & & & & & & & & & & *: { ; check the 'querytype' with the defined value above ; check that the : in front of realname is in the right place if ($2 == $$whoexec.queryt) && ($findtok($rawmsg,$wildtok($rawmsg,:*,2,32),1,32) == 15) { ; check if nick '$8' is in the IAL list if ($ial($8)) { ; not already marked if (!$wildtok($ial($8).mark,whoexec-*,1,32)) { ; increase item 'last' hinc -m $+(whoexec.,$cid,.ial) last ; add mode '$2-' to the hashtable with item name that 'last' has hadd $+(whoexec.,$cid,.ial) $hget($+(whoexec.,$cid,.ial),last) $ctime $3-7 $9-12 : $+ $13- ; add the info to the IAL .ialmark $8 $ial($8).mark $+(whoexec-,$hget($+(whoexec.,$cid,.ial),last)) } ; already marked else { ; replace the info to the IAL hadd $+(whoexec.,$cid,.ial) $gettok($wildtok($ial($8).mark,whoexec-*,1,32),2,45) $ctime $3-7 $9-12 : $+ $13- } } ; check that nick '$8' is in the hash table or nick '$8' matches an item in the hash table or channel '$3' is in the table and channel '$3' is not a '*' if ($hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($8) *,0,w).data > 0) || ($hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($8) *,0,wW).data) || (($hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($3) *,0,w).data > 0) && ($3 != *)) { ; stop mirc from showing this raw haltdef ; part for 'nick' ; set var var %x = $hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($8) *,0,w).data ; loop while (%x) { ; not for update only if ($gettok($hget($+(whoexec.queue.,$cid,.item),$hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($8) *,%x,w).data),2-,32) != -u) { ; run the alias that is in the hash table $whoexec.replace($gettok($rawmsg,5-,32),$gettok($hget($+(whoexec.queue.,$cid,.item),$hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($8) *,%x,w).data),2-,32)) } ; next dec %x } ; part for '#channels' ; '$3' is not a * if ($3 != *) { ; set a var var %x = $hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($3) *,0,w).data ; loop as long as '%x' is greater then 0 while (%x) { ; not for update only if ($gettok($hget($+(whoexec.queue.,$cid,.item),$hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($3) *,%x,w).data),2-,32) != -u) { ; run the alias that is in the hash $whoexec.replace($gettok($rawmsg,5-,32),$gettok($hget($+(whoexec.queue.,$cid,.item),$hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($3) *,%x,w).data),2-,32)) } ; decrease '%x' go on to the next match dec %x } } ; part for wildcards in 'nick' ; set a var var %x = $hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($8) *,0,wW).data ; loop as long as '%x' is greater then 0 while (%x) { ; not for update only if ($gettok($hget($+(whoexec.queue.,$cid,.item),$hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($8) *,%x,wW).data),2-,32) != -u) && ($gettok($hget($+(whoexec.queue.,$cid,.item),$hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($8) *,%x,wW).data),1,32) != $whoexec.lower($8)) { ; run the alias that is in the hash table $whoexec.replace($gettok($rawmsg,5-,32),$gettok($hget($+(whoexec.queue.,$cid,.item),$hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($8) *,%x,wW).data),2-,32)) } ; decrease '%x' go on to the next match dec %x } } } } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RAW 315 END WHO /WHO LIST. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 315 :End of /WHO list. raw 315:& & End of /WHO list.: { ; check if the hash table exists if ($hget($+(whoexec.queue.,$cid,.item))) { ; stop mirc from showing this raw haltdef ; set a var var %x = $numtok($2,44) ; loop through the things in '$2' that are seperated by a , while ($gettok($2,%x,44)) { ; loop as long as there is a match while ($hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($gettok($2,%x,44)) *,0,w).data) { ; check if '$gettok($2,%x,44)' is a channel if ($left($gettok($2,%x,44),1) isin $chantypes) { ; set a var var %cmd = $+(.,$chr(32),$gettok($hget($+(whoexec.queue.,$cid,.item),$hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($gettok($2,%x,44)) *,1,w).data),2-,32),$chr(32),.) ; replace here all ' &things ' with a space var %cmd = $replace(%cmd,$+($chr(32),&c,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&u,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&i,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&h,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&s,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&n,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&f,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&d,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&l,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&a,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&r,$chr(32)),$chr(32)) var %cmd = $replace(%cmd,$+($chr(32),&all,$chr(32)),$chr(32)) ; not for update if ($mid(%cmd,3,-2) != -u) { ; run the command and send the channel '$gettok($2,%x,44)' and 'End of /WHO list.' to it $mid(%cmd,3,-2) $gettok($2,%x,44) End of /WHO list. } } ; delete the item from the hash table hdel $+(whoexec.queue.,$cid,.item) $hfind($+(whoexec.queue.,$cid,.item),$whoexec.lower($gettok($2,%x,44)) *,1,w).data } ; decrease '%x' go on to the next nick/channel dec %x } ; disable the group whoexec.disable } } ; end of '#whoexec' group #whoexec end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.LOWER ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $whoexec.lower(nick/chan) alias -l whoexec.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 WHOEXEC.REPLACE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $whoexec.replace(,) alias -l whoexec.replace { ; save '. $2 .' in a var var %return = $+(.,$chr(32),$2,$chr(32),.) ; tokenize '$1' tokenize 32 $1 ; replace each '&' with their value var %return = $replace(%return,$+($chr(32),&c,$chr(32)),$+($chr(32),$1,$chr(32))) var %return = $replace(%return,$+($chr(32),&u,$chr(32)),$+($chr(32),$2,$chr(32))) var %return = $replace(%return,$+($chr(32),&i,$chr(32)),$+($chr(32),$3,$chr(32))) var %return = $replace(%return,$+($chr(32),&h,$chr(32)),$+($chr(32),$4,$chr(32))) var %return = $replace(%return,$+($chr(32),&s,$chr(32)),$+($chr(32),$5,$chr(32))) var %return = $replace(%return,$+($chr(32),&n,$chr(32)),$+($chr(32),$6,$chr(32))) var %return = $replace(%return,$+($chr(32),&f,$chr(32)),$+($chr(32),$7,$chr(32))) var %return = $replace(%return,$+($chr(32),&d,$chr(32)),$+($chr(32),$8,$chr(32))) var %return = $replace(%return,$+($chr(32),&l,$chr(32)),$+($chr(32),$9,$chr(32))) var %return = $replace(%return,$+($chr(32),&a,$chr(32)),$+($chr(32),$10,$chr(32))) ; check raw setting if ($whoexec.raw == 1) { ; replace normal var %return = $replace(%return,$+($chr(32),&r,$chr(32)),$+($chr(32),$11-,$chr(32))) var %return = $replace(%return,$+($chr(32),&all,$chr(32)),$+($chr(32),$1-,$chr(32))) } ; else else { ; delete the : in front of realname var %return = $replace(%return,$+($chr(32),&r,$chr(32)),$+($chr(32),$right($11-,-1),$chr(32))) var %return = $replace(%return,$+($chr(32),&all,$chr(32)),$+($chr(32),$1-10 $right($11-,-1),$chr(32))) } ; return the result return $mid(%return,3,-2) } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.DISABLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; this alias will only disable the group '#whoexec' if it is nolonger needed (checks all connections) alias -l whoexec.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($+(whoexec.queue.,$scid(%x),.item),0).item == 1) { ; free the hash table hfree $+(whoexec.queue.,$scid(%x),.item) } ; more then 1 item in the 'item' queue elseif ($hget($+(whoexec.queue.,$scid(%x),.item),0).item > 1) { ; stop return } ; increase '%x' and go on to the next connection id inc %x } ; disable the '#whoexec' group .disable #whoexec } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.QUEUE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $1 = table, $2- = thing alias whoexec.queue { ; there is a 2nd parameter and mode '$2-' is not already in the queue if ($2 != $null) && ((!$hfind($1,$2-)) || ($hfind($1,$2-).data == 0)) { ; increase item 'last' hinc -m $1 last ; add mode '$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($+(whoexec.queue.,$cid,.item))) { ; free the hash table hfree $+(whoexec.queue.,$cid,.item) } ; clear the queue $whoexec.queue($+(whoexec.queue.,$cid)).clear ; disable the group whoexec.disable } ; AUTO-UPDATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; JOIN EVENT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; on *:join:#:{ ; we join first chan if ($nick == $me) && (!$timer([ [ $cid ] $+ ] .whoexec.update)) { ; start timer .timer $+ $cid $+ .whoexec.update 1 $$whoexec.update.delay whoexec.update } } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.UPDATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; alias whoexec.update { ; on 0 channels if ($comchan($me,0) == 0) { !return } ; set var var %c = $whoexec.update.sort, %x = 1 ; loop while (%x <= $numtok(%c,32)) { ; request info whoexec -u $comchan($me,$gettok($gettok(%c,%x,32),2,46)) ; next chan inc %x } ; start timer .timer $+ $cid $+ .whoexec.update 1 $$whoexec.update.delay whoexec.update } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ALIAS WHOEXEC.UPDATE.SORT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; $whoexec.update.sort ; sorts channels where the IAL is not updated ; . ; 127.1 <= means 127 users on channel 1 alias -l whoexec.update.sort { ; set a var var %x = 1, %c ; loop through all common channels that we have with ourself while (%x <= $comchan($me,0)) { ; check if the ial is updated and we are not alone there if ($chan($comchan($me,%x)).ial == $true) && ($nick($comchan($me,%x),0) > 1) { ; add it to a var var %c = $addtok(%c,$+($nick($comchan($me,%x),0),.,%x),32) } ; go to the next channel inc %x } ; return it sorted return $sorttok(%c,32,n) } ; start of group whoexec.example ; (set to on or write '/enable #whoexec.example' to set these examples on #whoexec.example off ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EXAMPLE 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; you would write '!who ' in #channel on *:text:!who *:channel: { if ($nick isop $chan) { whoexec $2 whoinfo $chan &n &c &u &h &i &s &f &d &l &a &r } } ; usage: /whoexec &all ; $1 = channel / nick to message, $2 = nick which who info is looked up alias -l whoinfo { msg $1 nick $2 ; channel $3 ; username $4 ; host $5 ; ip $6 ; server $7 ; usermodes $8 ; hopcount $9 ; idletime $10 ; authed as $11 ; realname $12- } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EXAMPLE 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; usage: /authban , on a channel alias authban { if ($network === QuakeNet) { !var %vhost = .users.quakenet.org } elseif ($network === UnderNet) { !var %vhost = .users.undernet.org } else { !var %vhost = .* } if ($+(*!*@*,%vhost) iswm $ial($1)) && (%vhost != .*) { mode $chan +b $address($1,2) kick $chan $1- } elseif ($whoexec($1,&a)) { mode $chan +b $+(*!*@,$ifmatch,%vhost) kick $chan $1- } else { whoexec $1 authban_ $chan $1 &u &h &a %vhost $2- } } ; chan nick user host account vhost reason alias -l authban_ { var %chan = $1 var %nick = $2 var %user = $3 var %host = $4 var %a = $5 var %vhost = $6 var %reason = $7- if (%a) { mode %chan +b $+(*!*@,%a,%vhost) kick %chan %nick %reason } else { mode %chan +b $mask($+(%nick,!,%user,@,%host),2) kick %chan %nick %reason } } ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EXAMPLE 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; usage: /ipban , on a channel alias ipban { whoexec $1 ipban_ $chan &i } ; usage: /whoexec ; $1 = channel / nick to message, $2 = ip alias -l ipban_ { mode $1 +b $+(*!*@,$2) } ; whoexec.example group end #whoexec.example end ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; EXAMPLE 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; usage: /authban , on a channel alias authban { if (!$chan) { !return } if ($network === QuakeNet) { !var %vhost = .users.quakenet.org } elseif ($network === UnderNet) { !var %vhost = .users.undernet.org } else { !var %vhost = .* } if ($me !isop $chan) && ($me !ishop $chan) { } elseif ($me !isop $chan) && ($me ishop $chan) && (($1 isop $chan) || ($1 ishop $chan)) { } else { if ($+(*!*@*,%vhost) iswm $ial($1)) && (%vhost != .*) { mode $chan +b $address($1,2) kick $chan $1- } elseif ($whoexec($1,&a)) { mode $chan +b $+(*!*@,$ifmatch,%vhost) kick $chan $1- } else { whoexec $1 authban_ $chan $1 &u &h &a %vhost $2- } } } ; chan nick user host account vhost reason alias -l authban_ { var %chan = $1 var %nick = $2 var %user = $3 var %host = $4 var %a = $5 var %vhost = $6 var %reason = $7- if (%a) { mode %chan +b $+(*!*@,%a,%vhost) kick %chan %nick %reason } else { mode %chan +b $mask($+(%nick,!,%user,@,%host),2) kick %chan %nick %reason } }