# 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) { $getopts(:args :opt_ "acdehrg:i:n:o:x:y:" $args) @ :lagtime = isnumber(b10 $args) ? shift(args) : 0 @ :contime = isnumber(b10 $args) ? shift(args) : 60 if (opt_h) { echo Disconnect disconnected servers (do nothing) echo usage: ${t} [minlag] [minconn] -options [message] echo -g * Match servergroups *. 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 -n N Act only on N matching servers. echo -y * Include userhost. echo -x * Exclude userhost. return } fe (g i o) foo { fe ($(opt_$foo)) bar { push :matches $serverctl(${foo}match $bar) } } @ :matches = #matches ? matches : serverctl(omatch *) @ :matches = filter(<*> $matches) @ :opt_a = !opt_a, :opt_c = !!opt_c @ :cmd = opt_r ? [reconnect] : [disconnect] fe ($shufflef($uniq($matches))) serv { @ :eserv = serversrefe($serv) if (opt_a && opt_c ^ isconnected($serv)) { } elsif (contime > time()-lag[$serv][connected]) { } elsif (lagtime > time()-lag[$serv][pingorpong]) { } elsif (opt_e && mychannels($serv)) { #} elsif (opt_r && serverwin($serv)) { } elsif (rmatch($serverctl(get $serv userhost) $opt_x)) { } elsif (rmatch($serverctl(get $serv userhost) $opt_y) || !opt_y) { $cmd $serv ${args?args:randomread(~/.BitchX/BitchX.quit)} if (opt_d) {server -d $serv} unless (--:opt_n) {break} } } } # Delete servers with no excuses. # alias.t server.del fe ($*) 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() } 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 if (isconnected($servernum())) {quote PING ${(lag[$servernum()][sping] = time()) - F} ${[.]==[$0]?S:[$*]}} # on #^pong 0 '\\[$S $servernick()\\] % \\[$S $servernick() ${lag[$servernum()][sping]-F}\\]' # on #-pong + * { @ :sv = servernum() @ lag[$sv][pong] = time() @ lag[$sv][ping] = isnumber(b10 $2) ? [$2] + 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 -ref sping.$sv 60 sping } # on #-connect + * { @ lag[$servernum()][connected] = time() @ lag[$servernum()][joining] = 0 userhost $servernick() -cmd {sping} } # 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) } } # on #?send_to_server 0 "% % JOIN *" { @ :serv = [$0] if (![$3]) { return 0 } elsif (count(, $3)) { } 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 $targs $rnd ${t} $min $max $srv $args\\\;$args } # HTTP connect proxy navigation. # on #-server_status + "% % delet*" purge serv[$0][proxy] on #-server_established + * { #fe ($last[$encodel($0:$1)][proxy]) foo { fe ($serv[$servernum()][proxy]) foo { repeat ${isnumber(b10 ${:bar=cut(6 : $foo)})?bar:1} { pause ${!(:bar=cut(7 : $foo))?0:isnumber(b10 $bar)?bar:[]} switch (${0+iptolong($cut(0 : $foo))} $: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} (*) {quote CONNECT $cut(0.1 : $foo) HTTP/1.0$chr(13 10)} } @ :proto = cut(5 : $foo) } @ :proto = cut(5 : $foo) } } # 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) } server.fadd ${isnumber(b10 $sv) ? serversref($sv) : sv} #@ last[$serversrefe()][proxy] = [$cut(0.5 : $sv):${cut(6 : $sv)-1} $px] @ serv[$servernum()][proxy] = [$cut(0.5 : $sv):${cut(6 : $sv)-1} $px] 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.servs 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) { @ :sw = :wr = winrefs() fe sw sw {@ sw = winserv($sw)} fe args arg {@ arg = ischannel($arg) ? chanwin($arg) : revw($copattern($arg sw wr))} fe args arg {unshift arg swap} window $args } # 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 $S, 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 $S } $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) }