# CETK epic Server Connection Management script 0.0 # unload cetk.connmgmt package cetk.connmgmt load functions load cetk.functions load commandqueues # Away management. fe (send_msg send_public send_action) foo {on #-$foo + * {if (isaway()){q1cmd 0 999 back}}} on #-idle + * { if (!A && 2 < cloak) {return} @ :int = cetk.away.int ? cetk.away.int : 20 @ :min = cetk.away.min ? cetk.away.min : 20 if ([$0] < min) {return} if ([$0] % int) {return} allservs q1cmd 0 9 away } alias away (args) { if (rmatch($servergroup($serv) $my.cloaknets)) {return} @ :sn = servernum() @ cetk[away][int] = isnumber(b10 $args) ? shift(args) : cetk[away][int] @ cetk[away][min] = isnumber(b10 $args) ? shift(args) : cetk[away][min] @ cetk[away][$sn] = args = args ? args : cetk[away][$sn] @ args = args ? args : [Sideways to the Sun.] //away -- $args :: /ctcp $servernick() clientinfo * :: gone for $tdiff2($E) as of $Z } alias back /away # Disconnect disconnected servers. # alias.t discdisc (args) { @ :allgroups = uniq($serverctl(allgroups)) @ :oxd = xdebug(dword) xdebug dword #echo $args $getopts(:args :opt_ "acdehrvf:g:i:m:n:o:s:x:y:" $args) @ :pongtime = isnumber(b10 $args) ? shift(args) : 0 @ :pingtime = isnumber(b10 $args) ? shift(args) : 90 @ :conntime = isnumber(b10 $args) ? shift(args) : 90 @ :actytime = isnumber(b10 $args) ? shift(args) : conntime if (opt_h) { echo Disconnect disconnected servers (do nothing) echo usage: ${t} [ping] [pong] [connect] [inactivity] -options [message] echo -g * Match (and apply numeric filters to) servergroups *. echo -f * Match 005 NETWORK *. echo -i * Match itsnames *. echo -o * Match ournames *. echo -a Act on all matching servers. echo -c Act only on connected servers. echo -d delete after /disconnect. echo -e ignore channeled servers. echo -r /reconnect, not /disconnect. echo -v Invert groups list. echo -s * match against server status. echo -m N Ignore first N matching servers for group. echo -n N Act only on N matching servers for group. echo -y * Include userhost OR nick masks. echo -x * Exclude userhost OR nick masks. xdebug $oxd return } @ :opt_g = :opt_g ? opt_g : [*] @ :opt_g = (opt_v ? remwws(/ $opt_g / $allgroups) : opt_g) @ :opt_a = !opt_a, :opt_c = !!opt_c @ :cmd = opt_r ? [reconnect] : [disconnect] #local fe ($opt_g) group { @ :keep = opt_m, :kill = opt_n if (0 > kill) {@ kill += #common($serverctl(gmatch $group) / $myservers(,))} fe ($shuffles($serverctl(gmatch $group))) serv { if (opt_a && opt_c ^ isconnected($serv)) { } elsif (opt_f && !rmatch($serverctl(get $serv 005 NETWORK) $opt_f)) { } elsif (opt_i && !rmatch($serverctl(get $serv itsname) $opt_i)) { } elsif (opt_o && !rmatch($serverctl(get $serv name) $opt_o)) { } elsif (opt_s && !rmatch($serverctl(get $serv status) $opt_s)) { } elsif (opt_x && (rmatch($serverctl(get $serv userhost) $opt_x) || rmatch($serverctl(get $serv nick) $opt_x))) { } elsif (opt_y &&!(rmatch($serverctl(get $serv userhost) $opt_y) || rmatch($serverctl(get $serv nick) $opt_y))) { } elsif (0 < keep--) { } elsif (isconnected($serv) && pongtime > lag[$serv][lag]) { } elsif (isconnected($serv) && pingtime > time()-lag[$serv][sping]) { } elsif (lag[$serv][connected] && (conntime > (time()-lag[$serv][connected]))) { } elsif (lag[$serv][activity] && (actytime > (time()-lag[$serv][activity]))) { } elsif (opt_e && mychannels($serv)) { } else { unless (0 <= --kill || !opt_n) {break} @ cetk.quitmsgs = cetk.quitmsgs ? cetk.quitmsgs : [~/.BitchX/BitchX.quit] $cmd $serv ${args?args:randomread($cetk.quitmsgs)} if (opt_d) {server -d $serv} } } } xdebug $oxd } # Delete servers with no excuses. # alias.t server.del fe ($*) serv {if (isnumber(b10 $serv)) {disconnect $serv;server -d $serv}} # Add/duplicate servers with no excuses. # alias.t server.fadd (ret) { @ :ret = #ret ? ret : servernum() fe ret foo { if (isnumber(b10 $foo)) { @ :spec = [name port pass nick group] fe spec spec {@ :bar#= serverctl(get $foo $spec)#[:]} @ :foo = bar } do { @ :sv = rand(0) } until (0 > servernum($sv)) @ :sv = 2**31 @ :sv = -1 - rand($sv) server -a $sv:$cut(1.9 : $foo) @ serverctl(set $servernum() name $cut(0 : $foo)) @ foo = servernum() purge serv[$foo] lag[$foo] } return $ret } # Translate servernames into IPs to avoid non-blocking dns issues. # alias.t server.ipfix { fe ($serverctl(omatch $*)) sn { @ :sn = isnumber(b10 $sn) ? sn : servernum($sn) @ :ht = serverctl(get $sn name) @ :ip = nametoip($ht) @ :lo = iptolong($ip) @ serverctl(set $sn name ${lo?ip:ht}) } } # Lag measurement system. # alias.t sping { @ :sv = servernum() @ :mk^= lag[mask] @ :mk^= lag[$sv][mask] if (isconnected($sv)) {quote PING ${mk ^ ((lag[$sv][sping] = time()) - F)} ${[.]==[$0]?S:[$*]}} } alias.t sping.lagged (args) if (islagged($shift(args))) {sping $args} # alias.t islagged (args) return ${ (args ? shift(args) : 90) < (time() - lag[$servernum()][pong]) } # on #^pong 0 '\\[$servername() $servernick()\\] % \\[$servername() $servernick() ${(lag[$servernum()][sping] - F) ^ lag[$servernum()][mask]}\\]' # on #-pong + * { @ :sv = servernum() @ :mk^= lag[mask] @ :mk^= lag[$sv][mask] @ lag[$sv][pong] = time() @ lag[$sv][ping] = (isnumber(b10 $2) ? ([$2] ^ mk) + F : lag[$sv][sping]) @ lag[$sv][lag] = lag[$sv][ping] ? lag[$sv][pong] - lag[$sv][ping] : [?] @ lag[$sv][pingorpong] = lag[$sv][ping] ? lag[$sv][ping] : lag[$sv][pong] timer -up -canc -ref sping.$sv 60 1cmd 20 sping if (isnumber(b10 $lag[$sv][lag]) && 19 < lag[$sv][lag]) { xecho -banner -window crap -level crap -- Excessive PONG $servernum() $1- \($lag[$sv][lag]\) } } # on #-server_established + * @ lag[$servernum()][joining] = time() # on #-connect + * { @ lag[$servernum()][connected] = time() @ lag[$servernum()][joining] = 0 #userhost $servernick() -cmd {sping} sping } # fe ($jotm(250 255 265 266)) foo { on #-$foo 1 * @serv[\$servernum()][$foo]=numbers($*) fe (if unless) cmd { alias.recurse 3 ${cmd}.$foo (word,val,args) ${cmd} \(val <= word\(\$word \$serv[\$servernum()][$foo]\)\) {$args} } } # fe (471 473 474 475 379 channel_sync) foo { on #?$foo ${isnumber($foo) ? 0 : [+]} * { @ lag[$servernum()][joining] = 0 ^timer -ref winser1 20 ^winservchans return $rmatch($1 $my.ignorebans) } } # Join flood control. # on #?send_to_server 0 "% % MODE *" { @ :group = servergroup() if (my[moderand][$group] && rand($my[moderand][$group])) {return 1} @ :serv = [$0] @ :time = time() if (time == lag[$serv][mode]) { qcmd 9 $2- return 1 } else { @ lag[$serv][mode] = time return 0 } } # on #?send_to_server 0 "% % JOIN *" { @ :serv = [$0] @ :group = servergroup() if (![$3]) { return 0 } elsif (count(, $3)) { } elsif (my[joinrand][$group] && rand($my[joinrand][$group])) { return 1 } elsif (lag[$serv][joining] > lag[$serv][pingorpong]) { } elsif (60 < time()-lag[$serv][pingorpong]) { } else { @ lag[$serv][joining] = time() return 0 } qcmd @ :chans = [$3] @ :ckeys = [$4] while (@chans) { @ :chan = beforr(, $chans) @ :ckey = beforr(, $ckeys) unless (@ckey) { @ :echan = encodel($chan) @ :ckey = pop(list[chan][$echan][keys]) unshift list[chan][$echan][keys] $ckey } fq1cmd 0 9 quote $2 $chan $ckey @ :chans = after(, $chans) @ :ckeys = after(, $ckeys) } return 1 } # Ping self at regular intervals. # alias.t deidle (args) { @ :min = isnumber(b10 $args) ? shift(args) : 60 @ :max = isnumber(b10 $args) ? shift(args) : 60 * min @ :srv = isnumber(b10 $args) ? shift(args) : servernum() @ :targs = [-ref ${t}.$srv] unless (isconnected($srv)) {return} while (args =~ [-*]) {push targs $shift(args)} @ :rnd = max - min @ :rnd = min + rand($rnd) @ :args = args ? args : [ping] @ :args = [\\\$urldecode\($urlencode($args)\)] scmd $srv defer timer -canc $targs $rnd ${t} $min $max $srv $args\\\;$args } # HTTP connect proxy navigation. # on #-server_status + "% % delet*" purge qcmd[$0] serv[$0] onecmd[$0] lag[$0];assign.purge list.*.srv.$servernum().* on #-server_established + * server.proxy.navigate est on #-odd_server_stuff - "\* http/*" server.proxy.navigate ht on #-odd_server_stuff - "\* * ccproxy * ready." server.proxy.navigate wg on #-odd_server_stuff - "\* * connect to * OK!" server.proxy.navigate wg on -451 * @ serv[$servernum()][user]=randomread(foou);quote USER $serv[$servernum()][user];nick.dict;@ lag[$servernum()][connected] = time() on -461 * @ serv[$servernum()][user]=randomread(foou);quote USER $serv[$servernum()][user];nick.dict;@ lag[$servernum()][connected] = time() # alias.t server.proxy.navigate (args) { #eval echo $serverctl(get $servernum() proto);assign.dump serv.$servernum().* @ :type = shift(args) @ lag[$servernum()][connected] = time() #echo $servernum() $serverctl(get $servernum() proto) $serv[$servernum()][next] if (([IRC]==serverctl(get $servernum() proto)) && (:foo = shift(serv[$servernum()][next]))) { #echo $servernum() ${0+iptolong($cut(0 : $foo))} PROXY switch (${0+iptolong($cut(0 : $foo))} $serv[$servernum()][proto]) { #(0 socks%) {xquote -u %04%01%$after(-2 % $int2url($cut(1 : $foo)))$int2url(1)%00$cut(0 : $foo)%00} #(% socks%) {xquote -u %04%01%$after(-2 % $int2url($cut(1 : $foo)))$int2url($iptolong($cut(0 : $foo)))%00} (% wingate) {quote open $split(: $cut(0.1 : $foo))} (% ) { quote USER $serv[$servernum()][user] nick.dict } (*) {quote CONNECT $cut(0.1 : $foo) HTTP/1.0$chr(13 10)} } @ serv[$servernum()][proto] = cut(5 : $foo) } elsif (serv[$servernum()][proxy]) { #echo $servernum() ${0+iptolong($cut(0 : $foo))} END 1cmd 2 quote USER $serv[$servernum()][user] 1cmd 2 nick.dict } } # alias.t server.proxy (px) { $getopts(:px :opt_ r $px) if (:opt_r) { fe px px { @ :ht = before(: $px:) @ :ht = isnumber(b10 $ht) ? ht : nametoip($ht) @ :px = ht ? unsplit(\: $ht $after(\: $px)) : px } } @ :sv = shift(px) until (index(+ $sv)) { @ :plus++ @ :sv = rest(1 $sv) } @ :foo = :foo ? foo : randomread(foou.$tolower($servergroup())) @ :foo = :foo ? foo : randomread(foou) ^set default_username $shift(foo) repeat 2 shift foo ^set default_realname ${index(: $foo) ? foo : after(: $foo)} server.fadd ${isnumber(b10 $sv) ? serversref($sv) : sv} @ lag[$servernum()][connected] = time() @ serv[$servernum()][next] = serv[$servernum()][proxy] = words($cut(0.5 : $sv):${isnumber(b10 ${:bar=cut(6 : $sv)})?bar:0} $px) if ((serv[$servernum()][proxy] !~ [127.*]) && 1<#assign.grep(serv.*.proxy $serv[$servernum()][proxy])) { echo duplicate: $serv[$servernum()][proxy] assign.grep serv.*.proxy $serv[$servernum()][proxy] call } shift serv[$servernum()][next] if (1 winvisible($win) ? [-] : [+] @ :con = isconnected($serv) ? [+] : [-] @ my[sw] = leftw(1 $numsort($my[sw] -$@serv)) @ my[ww] = leftw(1 $numsort($my[ww] -$@win)) if (chan == [.] && 0 <= winserv($win)) { } elsif (0 <= findw($chan $mychannels(#$win))) { } elsif (rmatch($win,$serv,$vis$con,$chan $*)) { xecho -banner -nolog -- $[$my[ww]]win $[$my[sw]]serv $chan } } } alias wsc.movenul (args) { $getopts(:args :opt_ m:r:sj $args) unless (#args) { echo Requires: -js [-r randfactor] [-m maxmoves] towin toserv wscmask ... return } @ :newwin = isnumber(b10 $args) ? shift(args) : winnum() @ :newserv = isnumber(b10 $args) ? shift(args) : winserv($newwin) @ :newserv = servergroups($newserv) @ :opt_m = opt_m ? opt_m : serverctl(get $servernum() 005 MAXCHANNELS) @ :opt_m = opt_m ? opt_m : 10 @ :opt_r = opt_r ? opt_r : 1 fe my.winservchans win serv chan { @ :spec++ @ :vis = 0 > winvisible($win) ? [-] : [+] @ :con = isconnected($serv) ? [+] : [-] if (!rmatch($win,$serv,$vis$con,$chan $args)) { } elsif (0 <= findw($chan $mychannels(#$win))) { } elsif (opt_s && win!=newwin && serv!=newserv) { @ :select++ @ :rand = rand($select) ? rand : spec } elsif (!rand($opt_r) && 0 <= --opt_m) { @ win = newwin @ serv = newserv if (opt_j) {xeval -w $win -s $serv join $chan} } } if (rand) { fe my.winservchans win serv chan { unless (--rand) { @ win = newwin @ serv = newserv if (opt_j) {xeval -w $win -s $serv join $chan} } } } } alias.t wsc.spread (args) { $getopts(:args :opt_ hm:s: $args) if (:opt_h) { echo /${t} -s [wscmask] -m [maxmoves] [destwindowlist] # Spread all unjoined channels amongst all servers in current servergroup. } @ :wins = serverctl(get $servernum() name) @ :wins = serverctl(omatch $wins) fe wins wins {@ wins = serverwin($wins)} @ :args = args ? args : uniq($wins) if (opt_s) { @ :opt_m = opt_m ? opt_m : #args while (opt_m && args) { wsc.movenul -m ${2**31} -r ${opt_m--} $shift(args) $opt_s } } else { @ :opt_s = replace(n,* n $wins) fe args arg { wsc.movenul -m ${2**31} -r ${++:foo} $arg $opt_s unless (--:opt_m) {break} } } } alias wsc.save (fn, args) { @ :fd=open($fn w) @ struct.savefd($fd cloak last my) @ write($fd set LOG $getset(LOG)) @ write($fd dnotify $notify()) fe ($revw($winrefs())) ref { @ write($fd if \(0 > winvisible\($ref\)\) \{window new number $ref\}) @ write($fd if \([$winnam($ref)] != winnam\($ref\)\) \{window $ref name "$winnam($ref)"\}) } @ write($fd while \($serverctl(max) > serverctl(max)\) {server -a $rand(0)}) fe ($myservers(.)) ref { @ :args = [name port nick] #fe args foo {@ foo = [serverctl\(set $ref $foo \$decode\($encode($serverctl(get $ref $foo))\)\),]} fe args foo {@ foo = [serverctl\(set $ref $foo $serverctl(get $ref $foo)\),]} @ write($fd @ $args) } @ close($fd) } alias wsc.add { @ :owsc = my.winservchans winservchans $* push my.winservchans $owsc } alias wsc.del { fe my.winservchans win serv chan { if (rmatch($win,$serv,$chan $*)) { @ win = serv = chan = [] } } } alias winservchans { @:utime=utime() @:myservers=[] @:fix=[] @:fixchan=[] @:fixserv=[] ^local zcmd. if (debug.winservchans) {echo $tdiffu($utime) start} if ((#)%3) { echo Your line is incorrectly formatted. } elsif (#) { @ :newwins = [] @ :nextnew = 2 @ my.winservchans = [] load.ircservs fe ($*) win serv chans { if (0==win) { @win=nextnew++ } elsif (0findw($win $winrefs())) {continue} @:winserv=winserv($win) @:open=!rmatch("$serverctl(get $winserv status)" "" clos* *connect*) @:ews=encode($winserv) @:servok=open&&(0<=winserv)&&(0<=findw($before(: $serv:) $winserv $serverourname($winserv) $servername($winserv))) @:chanok=match($chan . $mychannels(#$win)) if (servok&&chanok) { if ([.]!=chan&&win!=chanwin($chan $winserv)) { @splice(fixchan ${2*rand(${1+numwords($fixchan)/2})} 0 $win $chan) } } elsif (!servok&&(match($serv $myservers))) { @splice(fixserv ${2*rand(${1+numwords($fixserv)/2})} 0 $win $serv) } elsif (E/60>=getset(cpu_saver_after)) { if (!rand(${++zrand[0]})) {^local zcmd[0] $win $serv .} } else { #echo $win $winvisible($win) $ews $zrand[$ews] @:eserv=serversrefe($winserv) if (open&&0<=winserv&&90time()-lag[$winserv][joining]) { #echo fail 2 } elsif (isnumber(b10 $lag[$winserv][lag])&&90=winnum($crapwin)?win:(winserv($win)==winserv($winnum($crapwin)))?crapwin:[$win server $serv $crapwin]} server $serv ${#key?[rejoin]:[channel]} $chan $key)) } ^assign -zrand[$foo] #echo $foo $win $serv $chan } if (debug.winservchans) {echo $tdiffu($utime) choose2} if (fix) { if (debug.winservchans) { xecho -banner -window crap -- $fixserv xecho -banner -window crap -- $fixchan xecho -banner -window crap -- $fix } unless (2&debug.winservchans) { window $fix } } if (debug.winservchans) {echo $chr(2)$tdiffu($utime)$chr(2) fix} } # alias.t wininit (fns,args) { @ :fns = #fns ? fns : [*] @ :fns = unsplit(, $fns) fe fns foo { ^assign foo $aliasctl(alias pmatch ${t}.$foo) } @ :fns = uniq($fns) fe fns foo { ^assign foo $(${foo}()) if (#foo%3) {echo Incorrectly formatted: $foo} } wsc.add $fns $args } # Swap to the windows with the named channels or servers. # alias.t wswap (args) { fe args arg { @ :servwin = :winrefs = winrefs() fe servwin servwin {@ servwin = winserv($servwin)} @ :mynuhs = mynuhs($servwin) @ :grpwin = :netwin = :ourwin = :itswin = servwin fe grpwin grpwin {@ grpwin = serverctl(get $grpwin group)} fe netwin netwin {@ netwin = serverctl(get $netwin 005 NETWORK), netwin = netwin ? netwin : [.]} fe ourwin ourwin {@ ourwin = serverctl(get $ourwin name)} fe itswin itswin {@ itswin = serverctl(get $itswin itsname)} @ :wins = [] if (isnumber(b10 $arg)) { } elsif (#serverctl(gmatch $arg)) { @ arg = serverctl(gmatch $arg) # } elsif (#serverctl(omatch $arg)) { # @ arg = serverctl(omatch $arg) # } elsif (#serverctl(imatch $arg)) { # @ arg = serverctl(imatch $arg) } elsif (#copattern($arg mynuhs servwin)) { @ arg = copattern($arg mynuhs servwin) } elsif (#copattern($arg grpwin servwin)) { @ arg = copattern($arg grpwin servwin) } elsif (#copattern($arg netwin servwin)) { @ arg = copattern($arg netwin servwin) } elsif (#copattern($arg ourwin servwin)) { @ arg = copattern($arg ourwin servwin) } elsif (#copattern($arg itswin servwin)) { @ arg = copattern($arg itswin servwin) } else { fe ($winrefs) win { if (#mychannels(#$win)) { fe ($pattern($arg $mychannels(#$win))) chan { xeval -s $winserv($win) -w $win push :wins \$chanwin($chan) } } elsif (isconnected($winserv($win)) && arg == [,]) { push :wins $win } } } if (:wins) { @ arg = filter(-* $wins), :wins = [] } else { fe arg arg {@ arg = copattern($arg servwin winrefs)} } @ :arg = revw($uniq($arg)) fe arg arg {window swap $arg} } } # Links mapper. on #-364 1 ** { unless (links.reap[$encode($0)]) { @ links.reap[$encode($0)] = 1 links.reap $0 } @ links.back[$encode($1)] = [$2] fe ($encode($2) $1 $encode($1) $2) bar baz { fe (all now) foo { ^assign.add links[$foo][$bar] $baz } } } on #-365 1 ** { @ links.reap[$encode($0)] = [] links.map $0 } alias.t links.map (serv default $servername(), bits, args) { @ :pipes = bits @ :pipes = msar(gr/1/ |/0/ /pipes) @ :eserv = encode($serv) @ :lserv = args ? rightw(1 . $args) : serv @ :link = -1 < findw($lserv $links[now][$eserv]) || !args @ :loop = -1 < findw($serv $args) @ :back = links[back][$eserv] @ :pipe = link ? [\\_] : [$chr(2) _$chr(2)] @ :flag = back ? [-] : [+] @ :flag = link ? [] : flag @ :flag = loop ? [*] : flag @ :alt = links[alt][$eserv] xecho -- * $pipes$pipe$serv $chr(2)$remws(/$flag ${#alt?#alt:[]})$chr(2) $alt @ links[alt][$eserv] = [] fe ($uniq($links[all][$eserv] $links[now][$eserv])) xserv { if ((link || !back) && 0 > findw($xserv $serv $args)) { if (:lastserv && !loop) { ${t} $lastserv ${bits}1 $args $serv } @ :lastserv = xserv } } if (:lastserv && !loop) { ${t} $lastserv ${bits}0 $args $serv } } alias.t links.reap { @ :serv = encode($0) fe ($links[now][$serv]) foo { if (0 > findw($foo $*)) { ${t} $foo $* @ links[now][$serv] = links[back][$serv] = [] } } } alias.t wimap (args) { who -line { push links[alt][$encode($5)] $strip(GH $2)$1 } -end { links.map $servername() } $unsplit(, ${args ? args : mychannels()}) } # Slow Paste # alias.t slowpaste (file, dest default $T, rep default 3) { @ :fh = open($file R) if (0 > fh) { echo usage: /${t} [filename] [dest] [waits] } else { @ :utime = utime() echo ${t} $* while ((:read = read($fh)) || !eof($fh)) { msg $dest ${#read?read:[ ]} unless (++:wait % rep) {wait} } echo ${t} $* \(Finished: $tdiff($tdiffu($utime))\) } @ close($fh) }