Create a gist now

Instantly share code, notes, and snippets.

@grawity /g_ts6.tcl
Last active Sep 17, 2016

What would you like to do?
# g_ts6.tcl - TS6 server link script for Eggdrop 1.6
#
# (c) 2013-2014 Mantas Mikulėnas <grawity@gmail.com>
# Released under the MIT Expat License <https://opensource.org/licenses/MIT>
set myserv fallen.sky
set mysid 1EG
set trusted {
services.int
}
set admins {
grawity
}
## misc util functions
proc chanref:join {hand} {
global members
expr {[incr members($hand)] == 1}
}
proc chanref:part {hand} {
global members
expr {[incr members($hand) -1] == 0}
}
proc chanref:get {hand} {
global members
if {[info exists members($hand)]} {
return $members($hand)
} else {
return 0
}
}
proc chanref:rename {oldhand newhand} {
global members
if {[info exists members($oldhand)]} {
set count $members($oldhand)
set members($newhand) $count
set members($oldhand) 0
return $count
} else {
putlog "!! chanref:rename($oldhand) unknown user"
return 0
}
}
proc chanref:quit {hand} {
global members
if {[info exists members($hand)]} {
set count $members($hand)
set members($hand) 0
return $count
} else {
putlog "!! chanref:quit($hand) unknown user"
return 0
}
}
proc lshift listVar {
upvar 1 $listVar l
set r [lindex $l 0]
set l [lreplace $l [set l 0] 0]
return $r
}
array unset baseary
array set baseary {
0 A 1 B 2 C 3 D 4 E 5 F 6 G 7 H 8 I 9 J
10 K 11 L 12 M 13 N 14 O 15 P 16 Q 17 R 18 S 19 T
20 U 21 V 22 W 23 X 24 Y 25 Z 26 0 27 1 28 2 29 3
30 4 31 5 32 6 33 7 34 8 35 9
}
proc lcontains {var str} {
expr {[lsearch -exact $var $str] >= 0}
}
proc istrusted {sid} {
global trusted
set serv [ts6:sid2serv $sid *]
if {$serv == "*"} {
return 0
} else {
lcontains $trusted $serv
}
}
proc isadmin {uid} {
global admins
set login [uid:get $uid LOGIN *]
if {$login == "*"} {
return 0
} else {
lcontains $admins $login
}
}
proc ts6:nextuid {} {
global baseary
global mysid
global ts6-uidcounter
set num [incr ts6-uidcounter]
set rad 0
set val 1
while {$num > $val} { set val [expr {pow(36,[incr rad])}] }
set result ""
while {$num > 0} {
set pow [expr {int(pow(36,$rad))}]
set red [expr {int($num/$pow)}]
incr num [expr {-($pow*$red)}]
append result $baseary($red)
incr rad -1
}
incr rad
while {$rad} {
append result A
incr rad -1
}
set pad [string repeat A [expr {6 - [string length $result]}]]
set uid $mysid$pad$result
return $uid
}
proc getflag {hand} {
return [expr {[matchattr $hand +o] ? "@" : ""}]
}
proc nicktolower {nick} {
string map {{[} \{ \\ | \] \}} [string tolower $nick]
}
## ts6 database functions
proc ts6:myuid {uid} {
global mysid
return [string match "$mysid*" $uid]
}
proc ts6:hand2nick {hand} {
global mysid
set prefix "$mysid-"
return "$prefix$hand"
}
proc ts6:nick2hand {nick} {
global mysid
set prefix "$mysid-"
if {[string match "$prefix*" $nick]} {
return [string range $nick [string length $prefix] end]
}
return ""
}
proc ts6:isuid {str} {
string match {[0-9][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z]} $str
}
proc ts6:issid {str} {
string match {[0-9][0-9A-Z][0-9A-Z]} $str
}
proc ts6:nick2uid {nick} {
global nick2uid
if {[ts6:isuid $nick]} {
return $nick
}
set nick [nicktolower $nick]
if {[info exists nick2uid($nick)]} {
return $nick2uid($nick)
}
return ""
}
proc ts6:ownnick2uid {nick} {
global nick2uid
set nick [nicktolower $nick]
if {[info exists nick2uid($nick)]} {
return $nick2uid($nick)
}
set uid [ts6:nextuid]
set nick2uid($nick) $uid
ts6:log "Alloc UID $uid for local user $nick"
return $uid
}
proc ts6:uid2nick {uid} {
uid:get $uid NICK $uid
}
proc ts6:serv2sid {serv} {
global serv2sid
if {[info exists serv2sid($serv)]} {
return $serv2sid($serv)
}
if {[ts6:issid $serv]} {
return $serv
}
return $serv
}
proc ts6:sid2serv {sid} {
sid:get $sid SERVER $sid
}
proc ts6:id2name {id} {
switch [string length $id] {
3 { ts6:sid2serv $id }
9 { ts6:uid2nick $id }
* { return $id }
}
}
proc ts6:changed-nick {uid oldnick newnick newts} {
if {$uid == "*"} {
set uid [ts6:nick2uid $oldnick]
}
uid:set $uid NICK $newnick
uid:set $uid NICKTS $newts
}
proc id:cmp {a b} {
set aname [ts6:id2name $a]
set bname [ts6:id2name $b]
string compare $aname $bname
}
## User DB
proc uid2sid {uid} {
string range $uid 0 2
}
proc uid:revset {nick uid} {
global nick2uid
set nick [nicktolower $nick]
if {$uid == "*"} {
if {[info exists nick2uid($nick)]} {
unset nick2uid($nick)
}
} else {
set nick2uid($nick) $uid
}
}
proc uid:revget {nick} {
global nick2uid
set nick [nicktolower $nick]
if {[info exists nick2uid($nick)]} {
return $nick2uid($nick)
}
return ""
}
proc uid:set {uid key val} {
global uidinfo
global sid2uids
if {$key == "NICK"} {
set old [uid:get $uid $key]
if {$old != ""} {
# nickname change
uid:revset $old *
} else {
# user introduced
set sid [uid2sid $uid]
dict set sid2uids($sid) $uid 1
# check if we already know this nick by another UID
set olduid [uid:revget $val]
if {$olduid != ""} {
ts6:log "Bug: Nickname $val{$uid} already known, forgetting old {$olduid}"
uid:forget $olduid
}
}
uid:revset $val $uid
}
dict set uidinfo($uid) $key $val
}
proc uid:get {uid key {def ""}} {
global uidinfo
if {[info exists uidinfo($uid)] &&
[dict exists $uidinfo($uid) $key]} {
dict get $uidinfo($uid) $key
} else {
return $def
}
}
proc uid:keys {uid} {
global uidinfo
if {[info exists uidinfo($uid)]} {
dict keys $uidinfo($uid)
} else {
return {}
}
}
proc uid:forget {uid} {
global sid2uids
global uidinfo
ts6:log "Forgetting user [uid:get $uid NICK]{$uid}"
set sid [uid2sid $uid]
if {[info exists sid2uids($sid)]} {
set sid2uids($sid) [dict remove $sid2uids($sid) $uid]
}
if {[info exists uidinfo($uid)]} {
set nick [uid:get $uid NICK]
if {$nick != ""} { uid:revset $nick * }
unset uidinfo($uid)
}
}
proc uid:cmp {a b} {
set aname [uid:get $a NICK $a]
set bname [uid:get $b NICK $b]
string compare $aname $bname
}
## Server DB
proc sid:revset {serv sid} {
global serv2sid
set serv [string tolower $serv]
if {$sid == "*"} {
if {[info exists serv2sid($serv)]} {
unset serv2sid($serv)
}
} else {
set serv2sid($serv) $sid
}
}
proc sid:set {sid key val} {
global sidinfo
global sid2sids
switch $key {
"SERVER" {
set old [sid:get $sid $key]
sid:revset $old *
sid:revset $val $sid
if {![info exists sid2uids($sid)]} {
set sid2uids($sid) {}
}
}
"UPLINK" {
dict set sid2sids($val) $sid 1
}
}
dict set sidinfo($sid) $key $val
}
proc sid:get {sid key {def ""}} {
global sidinfo
if {[info exists sidinfo($sid)] && [dict exists $sidinfo($sid) $key]} {
dict get $sidinfo($sid) $key
} else {
return $def
}
}
proc sid:keys {sid} {
global sidinfo
if {[info exists sidinfo($sid)]} {
dict keys $sidinfo($sid)
} else {
return {}
}
}
proc sid:forget {sid} {
global sid2sids
global sid2uids
global sidinfo
ts6:log "Forgetting server [sid:get $sid SERVER ?]{$sid}"
if {[info exists sid2sids($sid)]} {
foreach downlink [dict keys $sid2sids($sid)] {
sid:forget $downlink
}
unset sid2sids($sid)
}
if {[info exists sid2uids($sid)]} {
foreach uid [dict keys $sid2uids($sid)] {
uid:forget $uid
}
unset sid2uids($sid)
}
if {[info exists sidinfo($sid)]} {
set serv [sid:get $sid SERVER]
if {$serv != ""} {
sid:revset $sid *
}
set uplink [sid:get $sid UPLINK]
if {[info exists sid2sids($uplink)]} {
set sid2sids($uplink) [dict remove $sid2sids($uplink) $sid]
}
unset sidinfo($sid)
}
}
proc sid:cmp {a b} {
set aname [sid:get $a SERVER $a]
set bname [sid:get $b SERVER $b]
string compare $aname $bname
}
## Channel DB
proc chants:set {chan ts} {
global chants
set chan [string tolower $chan]
set chants($chan) $ts
}
proc chants:get {chan} {
global chants
set chan [string tolower $chan]
if {![info exists chants($chan)]} {
set chants($chan) [unixtime]
}
return $chants($chan)
}
## server functions
proc ts6:put {msg} {
global ts6-idx
putlog "output: $msg"
putdcc ${ts6-idx} $msg
}
proc ts6:sput {msg} {
global mysid
ts6:put ":$mysid $msg"
}
proc ts6:cput {msg} {
global ts6-mynick
ts6:put ":[ts6:ownnick2uid ${ts6-mynick}] $msg"
}
proc ts6:msg {targ msg} {
ts6:cput "PRIVMSG $targ :$msg"
}
proc ts6:cmsg {uid chan msg} {
ts6:cput "PRIVMSG $chan :[ts6:uid2nick $uid]: $msg"
}
proc ts6:note {targ msg} {
ts6:cput "NOTICE $targ :$msg"
}
proc ts6:cnote {uid chan msg} {
ts6:cput "NOTICE $uid :\[$chan\] $msg"
}
proc ts6:kill {uid msg} {
global myserv
ts6:log "Killing user [uid:get $uid NICK *]{$uid} ($msg)"
ts6:sput "KILL $uid :$myserv ($msg)"
uid:forget $uid
}
proc ts6:log {msg} {
global ts6-eob
putlog $msg
if {${ts6-eob}} {
ts6:msg "#services" $msg
}
}
proc ts6:introduce {hand} {
global myserv
global ts6-introduced
global ts6-mynick
global uptime
set nick [ts6:hand2nick $hand]
set uid [ts6:ownnick2uid $nick]
if {![info exists ts6-introduced($uid)]} {
ts6:log "Burst own user $hand as $nick{$uid}"
uid:set $uid NICK $nick
uid:set $uid USERNAME $hand
uid:set $uid HOSTNAME $myserv
uid:set $uid REALNAME $hand
ts6:sput "UID $nick 1 $uptime +i $hand $myserv 0 $uid :$hand"
set ts6-introduced($uid) $uid
}
return $uid
}
proc ts6:connect {host port} {
global botnet-nick
global myserv
global mysid
global myuid
global uptime
global nick2uid
global uidinfo
global serv2sid
global sidinfo
global sid2uids
global sid2sids
global ts6-introduced
global ts6-idx
global ts6-uidcounter
global ts6-mynick
global members
global chants
global ts6-eob
set idx [connect $host $port]
array unset nick2uid *
array unset uidinfo *
array unset serv2sid *
array unset sidinfo *
array unset sid2uids *
array unset sid2sids *
array unset ts6-introduced *
set ts6-idx $idx
set ts6-uidcounter 0
set ts6-mynick [ts6:hand2nick ${botnet-nick}]
array unset members *
array unset chants *
set ts6-eob 0
set myuid [ts6:ownnick2uid ${ts6-mynick}]
sid:set $mysid CAPS "ENCAP EUID EX IE QS SERVICES TB"
sid:set $mysid SERVER $myserv
sid:set $mysid HOPS 0
sid:set $mysid DESC "Eggdrop pseudoserver"
putdcc $idx "PASS jilles TS 6 :$mysid"
putdcc $idx "CAPAB :[sid:get $mysid CAPS]"
putdcc $idx "SERVER [sid:get $mysid SERVER] [sid:get $mysid HOPS] :[sid:get $mysid DESC]"
uid:set $myuid NICK ${ts6-mynick}
uid:set $myuid USERNAME ${botnet-nick}
uid:set $myuid HOSTNAME $myserv
uid:set $myuid REALNAME "${botnet-nick} (bot)"
ts6:sput "UID [uid:get $myuid NICK] 1 $uptime +Sio [uid:get $myuid USERNAME] [uid:get $myuid HOSTNAME] 0 $myuid :[uid:get $myuid REALNAME]"
ts6:cput "ENCAP * LOGIN Fallen"
array unset skip
set sjoin "@$myuid"
foreach sub [whom 0] {
set hand [lindex $sub 0]
set flag [lindex $sub 3]
if {![info exists skip($hand)]} {
chanref:join $hand
set skip($hand) 1
set uid [ts6:introduce $hand]
set prefix [expr {$flag == "" ? "" : "+"}]
lappend sjoin $prefix$uid
}
}
chants:set "#partyline" $uptime
ts6:sput "SJOIN $uptime #partyline +nt :$sjoin"
ts6:sput "TB #partyline $uptime ${ts6-mynick} :Direct link to ${ts6-mynick}'s partyline channel"
ts6:sput "SJOIN [unixtime] #nullroute + :$myuid"
control $idx ts6:tryhandle
}
proc ts6:eob {} {
global myuid
ts6:sput "SJOIN [chants:get "#services"] #services + :@$myuid"
}
proc ts6:authed {sid uid oldlogin newlogin} {
}
proc ts6:deauthed {sid uid oldlogin} {
}
proc ts6:tryhandle {idx input} {
if {[catch {ts6:handler $idx $input} emsg eopt] != 0} {
ts6:log "Handler error: $emsg"
foreach {k v} [dict get $eopt -errorstack] {
ts6:log " - $k: $v"
}
ts6:log "Continuing operation."
}
}
proc ts6:handler {idx input} {
global ts6-mynick
global ts6-eob
global myuid
global mysid
global myserv
global version
global peersid
global trusted
set input [rparse $input]
putlog "input{$idx} $input"
set prefix ""
set cmd [lindex $input 0]
if {[string index $cmd 0] == ":"} {
set prefix [string range [lshift input] 1 end]
set cmd [lindex $input 0]
}
switch [lindex $input 0] {
AWAY {
uid:set $prefix AWAY [lindex $input 1]
}
CAPAB {
set capab [sid:get $peersid CAPS]
lappend capab {*}[lindex $input 1]
sid:set $peersid CAPS [lsort $capab]
}
ENCAP {
set mask [lindex $input 1]
set input [lrange $input 2 end]
if {$mask == "*" || $mask == $myserv} {
switch [lindex $input 0] {
CERTFP { uid:set $prefix FPRINT [lindex $input 1] }
LOGIN { uid:set $prefix LOGIN [lindex $input 1] }
SU {
set uid [lindex $input 1]
set login [lindex $input 2]
set serv [ts6:sid2serv $prefix]
set nick [ts6:uid2nick $uid]
if {$login == "" || $login == "0"} {set login "*"}
if {[lcontains $trusted $serv]} {
set oldlogin [uid:get $uid LOGIN *]
uid:set $uid LOGIN $login
if {$login == "*"} {
ts6:log "Auth: $nick{$uid} deauthed by $serv{$prefix}"
ts6:deauthed $prefix $uid $oldlogin
} else {
ts6:log "Auth: $nick{$uid} authed as $login by $serv{$prefix}"
ts6:authed $prefix $uid $oldlogin $login
}
} else {
if {$login == "*"} {
ts6:log "Auth: Rejected: $nick{$uid} deauth by $serv{$prefix}"
} else {
ts6:log "Auth: Rejected: $nick{$uid} auth as $login by $serv{$prefix}"
}
}
}
GCAP { sid:set $prefix CAPS [lsort [lindex $input 1]] }
}
}
}
EUID {
set nick [lindex $input 1]
set uid [lindex $input 8]
if {[ts6:myuid $nick] || [ts6:myuid $uid]} {
ts6:kill $uid "Impostor!"
return 1
}
ts6:log "User: $nick{$uid} via [sid:get $prefix SERVER]{$prefix}"
uid:set $uid NICK $nick
uid:set $uid NICKTS [lindex $input 3]
uid:set $uid USERNAME [lindex $input 5]
uid:set $uid HOSTNAME [lindex $input 6]
uid:set $uid LOGIN [lindex $input 10]
uid:set $uid REALNAME [lindex $input 11]
}
JOIN {
set nick [ts6:uid2nick $prefix]
}
KICK {
set chan [lindex $input 1]
set victimuid [lindex $input 2]
set msg [lindex $input 3]
if {$victimuid == $myuid} {
ts6:put ":$victimuid JOIN [unixtime] $chan +"
}
}
KILL {
set actoruid $prefix
set victimuid [lindex $input 1]
set killpath [lindex $input 2]
set actornick [ts6:uid2nick $actoruid]
set victimnick [ts6:uid2nick $victimuid]
if {[ts6:myuid $victimuid]} {
set victimhand [ts6:nick2hand $victimnick]
} else {
ts6:log "Kill: $victimnick{$victimuid} by $actornick{$actoruid} via $killpath"
uid:forget $victimuid
}
#chanref:quit $victimhand
#partyline:offline $victimhand *
#partyline:online $victimhand *
#global uptime
#ts6:put ":$victimuid JOIN [unixtime] #partyline +"
#ts6:cput "TMODE $uptime #partyline +v $victimuid"
}
MOTD {
set sid [lindex $input 1]
if {$sid == $mysid} {
global botnet-nick
#ts6:sput "422 $prefix :MOTD File is missing"
ts6:sput "372 $prefix :I'm ${botnet-nick}, an Eggdrop bot."
foreach line [do:pmap $mysid [uid2sid $prefix]] {
ts6:sput "372 $prefix :- $line"
}
ts6:sput "376 $prefix :End of /MOTD"
}
}
NICK {
set oldnick [ts6:uid2nick $prefix]
set newnick [lindex $input 1]
set newts [lindex $input 2]
if {[ts6:myuid $newnick]} {
ts6:kill $prefix "Impostor!"
return 1
}
ts6:changed-nick $prefix $oldnick $newnick $newts
dccputchan 0 "$oldnick is now known as $newnick"
}
PASS {
set peersid [lindex $input 4]
}
PING {
set origin [lindex $input 1]
set dest [lindex $input 2]
if {$prefix == "" && ${ts6-eob} == 0} {
ts6:eob
set ts6-eob 1
ts6:put "PONG $origin"
} elseif {$dest == ""} {
ts6:sput "PONG $origin"
} else {
ts6:sput "PONG $myserv $origin"
}
}
PRIVMSG {
set nick [ts6:uid2nick $prefix]
set chan [lindex $input 1]
set msg [lindex $input 2]
if {$chan == "#partyline"} {
if {[string match "\x01ACTION *\x01" $msg]} {
dccputchan 0 "* $nick$chan [string range $msg 8 [expr [string length $msg] - 2]]"
} elseif {[string match "\x01*\x01" $msg]} {
dccputchan 0 "-$nick$chan- [string range $msg 1 [expr [string length $msg] - 2]]"
} else {
dccputchan 0 "<$nick$chan> $msg"
}
}
if {[string match "#*" $chan] && [string match ".*" $msg]} {
switch [lindex $msg 0] {
".raw" {
if {[isadmin $prefix]} {
ts6:put [join [lrange $msg 1 end]]
} else {
ts6:cnote $prefix $chan "Access denied."
}
}
".sput" {
if {[isadmin $prefix]} {
ts6:sput [join [lrange $msg 1 end]]
} else {
ts6:cnote $prefix $chan "Access denied."
}
}
".cput" {
if {[isadmin $prefix]} {
ts6:cput [join [lrange $msg 1 end]]
} else {
ts6:cnote $prefix $chan "Access denied."
}
}
".kill" {
if {[isadmin $prefix]} {
set nick [lindex $msg 1]
set msg [join [lrange $msg 2 end]]
set uid [ts6:nick2uid $nick]
ts6:kill [ts6:nick2uid $nick] $msg
} else {
ts6:cnote $prefix $chan "Access denied."
}
}
".changets" {
if {![isadmin $prefix]} {
ts6:cnote $prefix $chan "Access denied."
return 1
}
set targetchan [lindex $msg 1]
set newts [lindex $msg 2]
if {$targetchan == ""} {
set targetchan $chan
}
set oldts [chants:get $targetchan]
if {$newts == ""} {
set newts [expr $oldts - 1]
}
if {$newts < $oldts} {
chants:set $targetchan $newts
ts6:sput "SJOIN $newts $targetchan + :@$myuid"
ts6:note $targetchan "Channel's TS changed by \002$nick\002."
ts6:msg $chan "Channel's TS lowered to $newts."
} else {
ts6:msg $chan "Channel's TS is already lower ($newts >= $oldts)."
}
}
".opme" {
if {![isadmin $prefix]} {
ts6:cnote $prefix $chan "Access denied."
return 1
}
set targetchan [lindex $msg 1]
if {$targetchan == ""} {
set targetchan $chan
}
ts6:cput "TMODE [chants:get $targetchan] $targetchan +o $prefix"
ts6:note $targetchan "Opped \002$nick\002 upon request."
}
".join" {
if {![isadmin $prefix]} {
ts6:cnote $prefix $chan "Access denied."
return 1
}
set targetchan [lindex $msg 1]
if {$targetchan == ""} {
ts6:msg $chan "Beeeeep."
} else {
ts6:sput "SJOIN [chants:get $targetchan] $targetchan + :$myuid"
}
}
".part" {
if {![isadmin $prefix]} {
ts6:cnote $prefix $chan "Access denied."
return 1
}
set targetchan [lindex $msg 1]
if {$targetchan == ""} {
set targetchan $chan
}
ts6:cput "PART $targetchan :ok"
}
".map" {
foreach line [do:pmap $mysid [uid2sid $prefix]] {
ts6:msg $chan $line
}
}
".users" {
foreach line [do:pusers] {
ts6:msg $chan $line
}
}
".servs" {
foreach line [do:pservs] {
ts6:msg $chan $line
}
}
".hello" {
set hand [nick2hand $nick]
if {$hand == "*"} {
set login [uid:get $prefix LOGIN *]
if {$login == "*"} {
ts6:cnote $prefix $chan \
"You are not logged in to services."
} else {
set user [uid:get $prefix USERNAME *]
set host [uid:get $prefix HOSTNAME *]
if {[adduser $login "$nick!$user@$host"] == 1} {
ts6:cnote $prefix $chan \
"Added you to the bot as $login."
} else {
ts6:cnote $prefix $chan \
"Someone already has an account '$login'."
}
}
} else {
ts6:cnote $prefix $chan "You're already known as $hand."
}
}
".whoami" {
set hand [nick2hand $nick]
set login [uid:get $prefix LOGIN *]
if {$login == "*"} {
ts6:cnote $prefix $chan "You are not logged in to services."
} else {
ts6:cnote $prefix $chan "Your services account is $login."
if {[isadmin $prefix]} {
ts6:cnote $prefix $chan "You are listed as my owner."
}
}
}
".caps" {
global sidinfo
foreach sid [lsort [array names sidinfo]] {
ts6:msg $chan "$sid = [sid:get $sid CAPS ?]"
}
}
".uid" {
set uid [lindex $msg 1]
if {$uid == ""} {
set uid $prefix
} else {
set uid [ts6:nick2uid $uid]
}
set nick [uid:get $uid NICK]
set sid [uid2sid $uid]
set serv [sid:get $sid SERVER]
set hops [sid:get $sid HOPS]
if {$uid == $prefix} {
ts6:msg $chan "You are $nick{$uid} from $serv{$sid}, $hops hops away from me."
} else {
ts6:msg $chan "User $nick{$uid} is from $serv{$sid}, $hops hops away from me."
}
foreach key [lsort [uid:keys $uid]] {
ts6:msg $chan " - $key = [uid:get $uid $key]"
}
}
".sid" {
set sid [lindex $msg 1]
if {$sid == ""} {
set sid [uid2sid $prefix]
} else {
set sid [ts6:serv2sid $sid]
}
set serv [sid:get $sid SERVER]
if {$sid == [uid2sid $prefix]} {
ts6:msg $chan "You are connected from $serv{$sid}."
} else {
ts6:msg $chan "Information about $serv{$sid}:"
}
foreach key [lsort [sid:keys $sid]] {
ts6:msg $chan " - $key = [sid:get $sid $key]"
}
}
}
}
}
QUIT {
uid:forget $prefix
}
SERVER {
set name [lindex $input 1]
set hops [lindex $input 2]
set desc [lindex $input 3]
if {$prefix == ""} {
ts6:log "Server: $name{$peersid} via self{$mysid}"
sid:set $peersid SERVER $name
sid:set $peersid HOPS $hops
sid:set $peersid UPLINK $mysid
sid:set $peersid DESC $desc
} else {
ts6:log "Server: $name{-} via $prefix{-}"
}
}
SID {
set name [lindex $input 1]
set hops [lindex $input 2]
set sid [lindex $input 3]
set desc [lindex $input 4]
ts6:log "Server: $name{$sid} via [ts6:sid2serv $prefix]{$prefix}"
sid:set $sid SERVER $name
sid:set $sid HOPS $hops
sid:set $sid UPLINK $prefix
sid:set $sid DESC $desc
}
SJOIN {
set ts [lindex $input 1]
set chan [lindex $input 2]
chants:set $chan $ts
}
SQUIT {
set sid [lindex $input 1]
set msg [lindex $input 2]
ts6:log "Lost server: [ts6:sid2serv $sid]{$sid} ($msg)"
sid:forget $sid
}
SVINFO {
putdcc $idx "SVINFO 6 6 0 :[unixtime]"
}
TRACE {
set traceeuid [lindex $input 1]
if {[ts6:myuid $traceeuid]} {
#set myversion "eggdrop-[lindex $version 0]"
#ts6:sput "200 $prefix Link $myversion ... $myserv"
#if {[string length $traceeuid] == 3} {
# set tracee [ts6:sid2serv $traceeuid]
#} else {
# set tracee [ts6:uid2nick $traceeuid]
# ts6:sput "204 $prefix User users $tracee\[?@?\] (?) ? ?"
#}
#ts6:sput "262 $prefix $tracee :End of TRACE"
}
}
UID {
set nick [lindex $input 1]
set uid [lindex $input 8]
if {[ts6:myuid $nick] || [ts6:myuid $uid]} {
ts6:kill $uid "Impostor!"
return 1
}
ts6:log "User: $nick{$uid} via [sid:get $prefix SERVER]{$prefix}"
uid:set $uid NICK $nick
uid:set $uid NICKTS [lindex $input 3]
uid:set $uid USERNAME [lindex $input 5]
uid:set $uid HOSTNAME [lindex $input 6]
uid:set $uid REALNAME [lindex $input 9]
}
VERSION {
set sid [lindex $input 1]
if {$sid == $mysid} {
set myversion "eggdrop-[lindex $version 0]"
ts6:sput "351 $prefix $myversion $myserv :eHI6 TS6ow $mysid"
}
}
WALLOPS {
set from [ts6:id2name $prefix]
set msg [lindex $input 1]
ts6:log "Wallops ($from): $msg"
}
WHOIS {
global botnet-nick
set arg [lindex $input 2]
set uid [ts6:nick2uid $arg]
if {$uid != ""} {
set nick [ts6:uid2nick $uid]
if {$uid == $myuid} {
set hand ${botnet-nick}
} else {
set hand [ts6:nick2hand $nick]
}
if {$hand != ""} {
ts6:sput "311 $prefix $nick $hand $myserv * :$hand"
ts6:sput "312 $prefix $nick $myserv :[sid:get $mysid DESC $myserv]"
if {$uid == $myuid} {
ts6:sput "313 $prefix $nick :is a Pseudo-server"
} else {
ts6:sput "330 $prefix $nick $hand :logged in as"
}
} else {
ts6:sput "311 $prefix $nick [uid:get $uid USERNAME ?] [uid:get $uid HOSTNAME ?] * :[uid:get $uid REALNAME ?]"
set sid [uid2sid $uid]
ts6:sput "312 $prefix $nick [sid:get $sid SERVER $sid] :[sid:get $sid DESC $sid]"
set login [uid:get $uid LOGIN *]
if {$login != "*"} {
ts6:sput "330 $prefix $nick $login :logged in to services as"
}
set hand [nick2hand $nick]
if {$hand != "*"} {
ts6:sput "330 $prefix $nick $hand@${botnet-nick} :recognized by bot as"
}
}
ts6:sput "320 $prefix $nick :has TS6 uid $uid"
} else {
ts6:sput "401 $prefix $arg :No such nick"
}
ts6:sput "318 $prefix $arg :End of /WHOIS"
}
}
return 0
}
proc reload {} { source scripts/g_ts6/g_ts6.tcl }
proc go {} { ts6:connect 127.0.0.1 194 }
proc redo {} {
global ts6-idx
killdcc ${ts6-idx}
source scripts/g_ts6/g_ts6.tcl
go
}
bind chon - * partyline:online
bind chof - * partyline:offline
bind chjn - * partyline:join
bind chpt - * partyline:part
bind chat - * partyline:msg
bind act - * partyline:act
bind nkch - * partyline:nick
proc partyline:online {hand idx} {
set uid [ts6:introduce $hand]
ts6:put ":$uid JOIN [unixtime] #nullroute +"
}
proc partyline:offline {hand idx} {
global ts6-introduced
set uid [ts6:introduce $hand]
if {[chanref:get $hand] == 0} {
ts6:put ":$uid QUIT :Left the partyline"
unset ts6-introduced($uid)
}
}
proc partyline:join {bot hand chan flag idx uh} {
global uptime
if {$chan == "0"} {
if {[chanref:join $hand]} {
set uid [ts6:introduce $hand]
ts6:put ":$uid JOIN $uptime #partyline +"
ts6:cput "TMODE $uptime #partyline +v $uid"
}
}
}
proc partyline:part {bot hand idx chan} {
global members
if {$chan == "0"} {
if {[chanref:part $hand]} {
set uid [ts6:introduce $hand]
ts6:put ":$uid PART #partyline"
}
}
}
proc partyline:msg {hand chan msg} {
if {$chan == "0"} {
set uid [ts6:introduce $hand]
ts6:put ":$uid PRIVMSG #partyline :$msg"
}
}
proc partyline:act {hand chan msg} {
if {$chan == "0"} {
set uid [ts6:introduce $hand]
ts6:put ":$uid PRIVMSG #partyline :\001ACTION $msg\001"
}
}
proc partyline:nick {oldhand newhand} {
chanref:rename $oldhand $newhand
set oldnick [ts6:hand2nick $oldhand]
set newnick [ts6:hand2nick $newhand]
set uid [ts6:nick2uid $oldnick]
set nickts [unixtime]
ts6:put ":$uid NICK $newnick $nickts"
ts6:changed-nick $uid $oldnick $newnick $nickts
}
proc do:pusers {} {
global uidinfo
set output {}
set fmt "%-9s %-15s %-15s %-30s"
lappend output [format $fmt UID NICK ACCOUNT SERVER]
lappend output [string repeat - 79]
foreach uid [lsort -command uid:cmp [array names uidinfo]] {
set sid [uid2sid $uid]
lappend output [format $fmt $uid \
[uid:get $uid NICK] \
[uid:get $uid LOGIN *] \
[string range [sid:get $sid SERVER] 0 29] \
]
}
return $output
}
proc do:pservs {} {
global sidinfo
global sid2uids
set output {}
set fmt "%-3s %2s %-32s %3s"
lappend output [format $fmt SID H# SERVER U#]
lappend output [string repeat - 79]
foreach sid [lsort [array names sidinfo]] {
if {[info exists sid2uids($sid)]} {
set usercount [llength [dict keys $sid2uids($sid)]]
} else {
set usercount 0
}
lappend output [format $fmt $sid \
[sid:get $sid HOPS 0] \
[sid:get $sid SERVER] \
$usercount \
]
}
return $output
}
proc lbranch {branches depth count strm strl} {
if {$depth > 0} {
if {$count > 0} {
set str $strm
} else {
set str $strl
}
} else {
set str ""
}
lreplace $branches $depth $depth $str
}
proc marked {x y str} {
if {$x == $y} {
return "\x02$str\x0f"
} else {
return $str
}
}
proc do:pmap {sids {mark ""} {depth 0} {branches {}}} {
global sid2sids
lappend branches ""
set output {}
set count [llength $sids]
foreach sid $sids {
incr count -1
set branches [lbranch $branches $depth $count " ├─" " └─"]
lappend output "[join $branches ""][marked $sid $mark [sid:get $sid SERVER "(split)"]]\[$sid\]"
if {[info exists sid2sids($sid)]} {
set links [lsort -command sid:cmp [dict keys $sid2sids($sid)]]
set branches [lbranch $branches $depth $count "" " "]
lappend output {*}[do:pmap $links $mark [expr $depth+1] $branches]
}
}
return $output
}
proc dcc:pusers {hand idx arg} {
foreach line [do:pusers] {putdcc $idx $line}
}
proc dcc:pservs {hand idx arg} {
foreach line [do:pservs] {putdcc $idx $line}
}
proc dcc:pmap {hand idx arg} {
global mysid
foreach line [do:pmap $mysid] {putdcc $idx $line}
}
bind dcc n "pusers" dcc:pusers
bind dcc n "pservs" dcc:pservs
bind dcc - "pmap" dcc:pmap
return "Done"
#
# vim: ts=4:sw=4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment