Auth-Update2

From Scriptwiki
Revision as of 13:57, 17 September 2009 by Vliedel (talk | contribs) (added some ^ to events, to make sure they're processed before other scripts)

Jump to: navigation, search

This snippet is a new version of Auth_update

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; AUTH_UPDATE2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
by Vliedel -- #vliedel @ QuakeNet
version 1.2 (written and tested on mIRC 6.35)
made for networks supporting WHOX
What does this script do?
- updates the auths of nicks and stores them in a hash table
- if a channel is too big, /who nick1,nick2,nick3 etc is done untill the auths for the channel is updated
- users who have a site with the auth in it will be saved without a /who
ie
"Vliedel" in "Vliedel.users.quakenet.org" will be treated as auth on the QuakeNet network
- users who are not authed (auth 0) will be checked every x time to see if they are authed yet
- script updates from largest to the smallest channel
How to use this script?
- config the options below
- /load -rs auth_update2.mrc to load the script
- script starts on load or on join
- to get the auth of a nick use
$auth(nick) or $auth(nick,cid)
- to get a nick from an auth use
$auth-nick(auth) or $auth-nick(auth,cid)
- to recheck a nick that was not authed by command use
/auth.update <nick>
note that rechecking is done automatically, only use this command if you really want to recheck quickly
- You can use the following example script to see when a nicks auth is updated
on *
SIGNAL:authupdate.new:{
if (!$2) { echo -ag $1 is not authed }
else { echo -ag $1 is authed as $2 }
}
- The following signal is send when a requested auth is updated (with /auth.update <nick>)
on *
SIGNAL:authupdate.req:{
if ($2 == $null) { echo -ag requested
$1 is not on a common chan }
elseif ($2 == 0) { echo -ag requested
$1 is not authed }
else { echo -ag requested
$1 is authed as $2 }
}
Note that these signals return $2 == $null when someone isn't on a common channel.
This may occur for example when someone parted a channel between the /who and the who reply.
Why is this script good?
- compared with my first auth_update, this script uses less resources, at the cost of a little bit more traffic
- sending /who chan for every channel is not needed and goes slow (lag)
- sending /who chan on join may cause Excess Flood or Max sendQ exceeded
- sending /who chan1,chan2,chan3 can be much faster, but only if there are not too many results (Max sendQ exceeded)
- unauthed users can auth without you knowing, so you need to check if they're authed every so many time.


SETTINGS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
maximum number of replies in a WHO, too high may cause 'Max sendQ exceeded' disconnection
too low may take the script a long time to update the auths, 1000 should be fine for most situations

alias -l max.replies { return 1000 }

maximum length of the /who <string>, too long may cause the server to ignore the command
too low may slow things down, 400 should be fine in most cases

alias -l max.len { return 400 }

minimum time (seconds) between two /who commands (default 10)

alias -l delay { return 10 }

time (seconds) between the checking if any unauthed users should be rechecked (default 120)

alias -l queue.delay { return 120 }

time (seconds) to recheck if an unauthed user is now authed (default 600)

alias -l queue.check { return 600 }

minimum ratio of (nicks with unknown auth) / (total nicks) in a channel to do /who #channel rather then /who nick,nick, (default 0.09)

alias -l min.ratio { return 0.09 }

minimum nr of nicks with unknown auth in a channel to do /who #channel rather then /who nick,nick, (default 10)

alias -l min.nicks { return 10 }

The networks the script is supposed to work on (case sensitive)
NOTE that the script ONLY works on networks supporting WHOX (ircu 2.10.* should work)

alias -l used.network {

 return $istokcs(QuakeNet UnderNet GameSurge HanIRC NetGamers OGameNet,$network,32)

}

For every network a check to see if a user has a site where his authname is in
$1 is the site

alias -l auth.in.site {

 var %n = $network
 if (%n === QuakeNet) { return $iif(*.users.quakenet.org iswm $1,$true) }
 elseif (%n === UnderNet) { return $iif(*.users.undernet.org iswm $1,$true) }
 elseif (%n === GameSurge) { return $iif(*.*.GameSurge iswm $1,$true) }
 elseif (%n === HanIRC) { return $iif(*.users.HanIRC.org iswm $1,$true) }
 elseif (%n === NetGamers) { return $iif(*.users.netgamers.org iswm $1,$true) }
 elseif (%n === OGameNet) { return $iif(*.user.OGameNet iswm $1,$true) }

}

For every network the method to return the auth from the site
$1 is the site

alias -l auth.from.site {

 var %n = $network
 if (%n === QuakeNet) { return $gettok($1,1,46) }
 elseif (%n === UnderNet) { return $gettok($1,1,46) }
 elseif (%n === GameSurge) { return $gettok($1,1,46) }
 elseif (%n === HanIRC) { return $gettok($1,1,46) }
 elseif (%n === NetGamers) { return $gettok($1,1,46) }
 elseif (%n === OGameNet) { return $gettok($1,1,46) }

}

$auth(nick [,cid]) returns the auth of the nick

alias auth {

 if (!$isid) { $iif($show,.auth,auth) $1- | return }
 if ($1 == $null) || ($2 !== $null && (!$scid($2) || !$2)) { return }
 return $gettok($hget($iif($2,$2,$cid) $+ .auths,$+(auth.,$comchan($1,1),$chr(44),$1)),1,32)

}

$auth-nick(auth [,cid]) returns the first nick with that auth

alias auth-nick {

 if ($1 == $null) || ($2 !== $null && (!$scid($2) || !$2)) { return }
 return $gettok($hfind($iif($2,$2,$cid) $+ .auths,$1,1,n).data,-1,44)

}

AUTH.UPDATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
/auth.update nick

alias auth.update {

 if (!$used.network) || (!$comchan($1,1)) { return }
 var %t = $cid $+ .auths , %a = $hget(%t,$+(auth.,$comchan($1,1),$chr(44),$1))
 if (0 * iswm %a) { hdel -w %t $+(auth.,*,$chr(44),$1) }
 if (!%a) || (0 * iswm %a) { au.update n $1 | hadd %t req. $+ $1 1 }
 else { .signal authupdate.req $1 %a }

}

AU.UPDATE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$1 = t/n/c/r (timer nick chan repeat)
[$1- = n nick]

alias -l au.update {

 var %t = $cid $+ .auths
 if (!$hget(%t)) { hmake %t }
 var %tim = au.update.delay. $+ $cid , %d = $hget(%t,delay)
 if ($ctimer == %tim) && ($1 !== r) { hadd -u $+ $delay %t delay 1 | au.who | return }
 if (!%d) || ($1 == r) { hadd -u $+ $delay %t delay 1 }
 if ((!$timer(%tim) && (%d || $1 == c)) || $1 == r) { .timer $+ %tim 1 $delay au.update }
 if (!%d && !$timer(%tim) && $1 !== c && $1 !== r) { au.who $iif($1 == n,$2) }

}

NICKLIST CHANGING EVENTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

on ^*:JOIN:#:{

 var %t = $cid $+ .auths
 if (!$used.network) { return }
 if ($nick == $me) { au.start | au.update c | return }
 if (!$hget(%t)) { return }
 if ($hfind(%t,$+(auth.*,$chr(44),$nick),1,w)) { hadd %t $+(auth.,$chan,$chr(44),$nick) $hget(%t,$v1) }
 elseif ($auth.in.site($site)) { au.upd.nick $nick $site }
 else { au.update n $nick }

}

on *:PART:#:{ au.part $chan $nick | au.upd.nick $nick $site $chan } on *:KICK:#:{ au.part $chan $knick | au.upd.nick $nick $site }

$1 = chan $2 = nick

alias -l au.part {

 var %t = $cid $+ .auths
 if (!$hget(%t)) { return }
 if ($2 == $me) {
   hdel -w %t auth. $+ $chan $+ ,*
   hdel %t ctime. $+ $chan
   var %i = $hfind(%t,req.*,0,w)
   while (%i) {
     var %it = $hfind(%t,req.*,%i,w) , %n = $gettok(%it,2,46)
     if (%n ison $1) && (!$comchan(%n,2)) { hdel %t %it | .signal authupdate.req %n }
     dec %i
   }
 }
 else {
   hdel %t $+(auth.,$1,$chr(44),$2)
   if ($hget(%t,req. $+ $2)) && (!$comchan($2,2)) { hdel %t req. $+ $2 | .signal authupdate.req $2 }
 }

}

on *:QUIT:{

 var %t = $cid $+ .auths
 if (!$hget(%t)) { return }
 hdel -w %t $+(auth.,*,$chr(44),$nick)
 if ($hget(%t,req. $+ $nick)) { hdel %t req. $+ $nick | .signal authupdate.req $nick }

}

on ^*:NICK:{

 var %i = $comchan($newnick,0) , %t = $cid $+ .auths
 if ($nick == $newnick) || (!$hget(%t)) { return }
 while (%i) {
   var %it = $+(auth.,$comchan($newnick,%i),$chr(44))
   $iif($hget(%t,%it $+ $nick),hadd,hdel) %t %it $+ $newnick $v1
   hdel %t %it $+ $nick
   dec %i
 }
 if ($hget(%t,req. $+ $nick)) { hadd %t req. $+ $newnick 1 | hdel %t req. $+ $nick }
 if ($auth.in.site($site)) { au.upd.nick $newnick $site }

}

AU.WHO ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
[$1 = nick]

alias -l au.who {

 var %t2 = $cid $+ .au.who
 if ($hget(%t2)) { hfree %t2 }
 hmake %t2
 if ($1) {
   var %who = $1 $+ ,,, $+ 137
   hadd %t2 -mask %who
   who %who n%nat,137
   return
 }
 var %i = $comchan($me,0) , %t = $cid $+ .auths , %sort , %ticks = $ticks
 while (%i) {
   var %sort = %sort $nick($comchan($me,%i),0) $+ . $+ %i
   dec %i
 }
 var %sort = $sorttok(%sort,32,n) , %i = $numtok(%sort,32) , %maxlen = $max.len , %n.max = $max.replies  , %time = $calc($ctime - $queue.check) , %ids , %n.w , %len
 while (%i) {
   var %c = $comchan($me,$gettok($gettok(%sort,%i,32),2,46)) , %n.0 = $hfind(%t,0 %c &,0,w).data , %n.c = $nick(%c,0)
   var %n.l = $calc(%n.c - $hfind(%t,$+(auth.,%c,$chr(44),*),0,w) + $iif(%time < $hget(%t,ctime. $+ %c),0,%n.0))
   if ($calc(%len + $len(%c) +1) > %maxlen) || ($calc(%n.w + %n.c) > %n.max) { dec %i | continue }
   if (%n.l > 1) && ((%n.l >= $min.nicks) || ($calc(%n.l / %n.c) >= $min.ratio)) {
     var %chans = %chans %c
     hadd %t ctime. $+ %c $ctime
     var %j = $nick(%c,0)
     while (%j) {
       var %n = $nick(%c,%j)
       if (!$hget(%t2,%n)) { hadd %t2 %n 1 | inc %n.w }
       dec %j
     }
     inc %len $calc($len(%c) +1)
   }
   dec %i
 }
 var %i = $comchan($me,0) , %nicks
 while (%i) {
   var %c = $comchan($me,%i)
   if (!$istok(%chans,%c,32)) {
     if ($calc($nick(%c,0) - $hfind(%t,$+(auth.,%c,$chr(44),*),0,w)) > 0) {
       var %j = $nick(%c,0)
       while (%j) {
         var %n = $nick(%c,%j)
         if ($calc(%len + $len(%n) +1) > %maxlen) { goto end }
         var %val = $hget(%t,$+(auth.,%c,$chr(44),%n))
         if (!$hget(%t2,%n)) && ((%val == $null) || ($gettok(%val,3,32) < %time)) { var %nicks = %nicks %n | hadd %t2 %n 1 | inc %n.w | inc %len $len(%n) }
         if (%n.w >= %n.max) { goto end }
         dec %j
       }
     }
     else {
       var %j = $hfind(%t,0 %c &,0,w).data
       while (%j) {
         var %it = $hfind(%t,0 %c &,%j,w).data , %n = $gettok(%it,2,44)
         if ($calc(%len + $len(%n) +1) > %maxlen) { goto end }
         if (!$hget(%t2,%n)) && ($gettok($hget(%t,%it),3,32) < %time) && (auth.* iswm %it) { var %nicks = %nicks %n | hadd %t2 %n 1 | inc %n.w | inc %len $len(%n) }
         if (%n.w >= %n.max) { goto end }
         dec %j
       }
     }
   }
   dec %i
 }
 :end
 var %who = $replace(%chans %nicks,$chr(32),$chr(44))
 if (%who) {
   var %who = %who $+ ,,, $+ 137
   hadd %t2 -mask %who
   who %who n%nat,137
   if (%len > $calc(%maxlen * 0.7)) || (%n.w > $calc(%n.max * 0.7)) { au.update r }
 }

}

RAW REPLIES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
RAW 354 SPECIAL WHO REPLY
354 <you> <nr> <nick> <auth>
354 Vliedel 137 sy rry

RAW 354:& 137 & &:{

 haltdef
 var %i = $comchan($3,0) , %t = $cid $+ .auths
 if ($hget(%t,req. $+ $3)) { hdel %t req. $+ $3 | .signal authupdate.req $3 $iif(%i,$4) }
 if (!%i) || (!$hget(%t)) { return }
 if ($gettok($hget(%t,$+(auth.,$comchan($3,1),$chr(44),$3)),1,32) !== $4) { .signal authupdate.new $3 $4 }
 while (%i) {
   var %c = $comchan($3,%i)
   hadd %t $+(auth.,%c,$chr(44),$3) $4 $iif(!$4,%c $ctime)
   dec %i
 }

}

RAW 315 WHO END
315 <you> <requested>  
End of /who list.
315 Vliedel #vliedel,,,137  
End of /WHO list.

RAW 315:& *,,,137 end of /WHO list.: {

 if ($hget($cid $+ .au.who,-mask) == $2) {
   var %who = $left($2,-6) , %i = $wildtok(%who,#*,0,44) , %t = $cid $+ .auths
   while (%i) {
     hadd %t ctime. $+ $wildtok(%who,#*,%i,44) $ctime
     dec %i
   }
   hfree $cid $+ .au.who
 }
 haltdef

}

STARTING AND STOPPING ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

on *:LOAD:{ scon -at1 au.load l } alias -l au.load {

 au.stop
 au.start
 au.update t

}

alias -l au.stop {

 .timer $+ au.update. $+ $cid off
 .timer $+ au.update.delay. $+ $cid off
 if ($hget($cid $+ .auths)) { hfree $v1 }
 if ($hget($cid $+ .au.who)) { hfree $v1 }

}

alias -l au.start {

 if (!$used.network) { return }
 if (!$hget($cid $+ .auths)) { hmake $cid $+ .auths }
 if (!$timer(au.update. $+ $cid)) { .timer $+ au.update. $+ $cid 0 $queue.delay au.update t }

}

on *:DISCONNECT:{ au.stop } on *:UNLOAD:{ scon -a au.stop }


IAL-UPDATING EVENTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

on ^*:TEXT:*:*:{ au.upd.nick $nick $site } on ^*:ACTION:*:*:{ au.upd.nick $nick $site } on ^*:NOTICE:*:*:{ au.upd.nick $nick $site } on ^*:RAWMODE:#:{ au.upd.nick $nick $site } on ^*:TOPIC:#:{ au.upd.nick $nick $site } on ^*:INVITE:#:{ au.upd.nick $nick $site } CTCP *:*:*:{ au.upd.nick $nick $site } RAW 352:& & & & & & & & *: { au.upd.nick $6 $4 }

$1 = nick $2 = site [ $3 = chan (exclude it)]

alias -l au.upd.nick {

 if (!$auth.in.site($2)) || (!$hget($cid $+ .auths)) { return }
 var %i = $comchan($1,0) , %t = $cid $+ .auths , %au = $auth.from.site($2)
 if (!%i) || (%i == 1 && $3) || ($hget(%t,$+(auth.,$comchan($1,1),$chr(44),$1)) == %au) { return }
 while (%i) {
   if ($comchan($1,%i) !== $3) { hadd %t $+(auth.,$v1,$chr(44),$1) %au }
   dec %i
 }
 .signal authupdate.new $1 %au

}

USED DATA/TIMERS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TABLE <cid>.auths
auth.<chan>,<nick> --> <auth> [chan ctime]
req.<nick> --> 1
ctime.<chan> --> <ctime>
delay --> <1/0/null>
TABLE <cid>.au.who
nick --> 1
-mask --> /who string
TIMER au.update.delay.<cid>
TIMER au.update.<cid>