tclserv

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ts62.disabled (21883B)


      1 namespace eval ts6 {
      2 proc ::ts6::b64e {numb} {
      3         set b64 [split "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" {}]
      4 
      5         set res ""
      6 	while {$numb != 0} {
      7 		append res [lindex $b64 [expr {$numb % 36}]]
      8 		set numb [expr {$numb / 36}]
      9 	}
     10 	if {[string length $res] == 0} {
     11 		set res "A"
     12 	}
     13         return [string reverse $res]
     14 }
     15 
     16 proc ::ts6::b64d {numb} {
     17         set b64 "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
     18 	set numb [string trimleft $numb "A"]
     19 	set res 0
     20 	for {set i 0} {$i<[string length $numb]} {incr i} {
     21 		set new [string first [string index $numb $i] $b64]
     22 		incr res [expr {$new * (36 * $i)+1}]
     23 	}
     24         return $res
     25 }
     26 }
     27 
     28 
     29 if {[info commands putdcc] != [list putdcc]} {
     30 	proc putdcc {idx text} {
     31 		puts $idx $text
     32 	}
     33 }
     34 
     35 if {[info commands putcmdlog] != [list putcmdlog]} {
     36 	proc putcmdlog {text} {
     37 		puts -nonewline stdout "(command) "
     38 		puts stdout $text
     39 	}
     40 }
     41 
     42 namespace eval ts6 {
     43 
     44 proc ::ts6::sendUid {sck nick ident host dhost uid {realname "* Unknown *"} {modes "+oiS"} {server ""}} {
     45 	if {""==$server} {set server $::sid($sck)}
     46 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $server]]}]]
     47 	append sid [::ts6::b64e $server]
     48 	set sendid [::ts6::b64e $uid]
     49 	set sendnn [string repeat "A" [expr {6-[string length $sendid]}]]
     50 	append sendnn $sendid
     51 	if {![tnda get "ts6/$::netname($sck)/euid"]} {
     52 		set sl [format ":%s UID %s 1 %s %s %s %s 0 %s%s :%s" $sid $nick [clock format [clock seconds] -format %s] $modes $ident $host $sid $sendnn $realname]
     53 	} {
     54 		set sl [format ":%s EUID %s 1 %s %s %s %s 0 %s%s %s * :%s" $sid $nick [clock format [clock seconds] -format %s] $modes $ident $dhost $sid $sendnn $host $realname]
     55 	}
     56 	tnda set "intclient/$::netname($sck)/${sid}${sendnn}" $uid
     57 	tnda set "nick/$::netname($sck)/${sid}${sendnn}" $nick
     58 	putdcc $sck $sl
     59 }
     60 
     61 proc ::ts6::topic {sck uid targ topic} {
     62 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]]
     63 	append sid [::ts6::b64e $::sid($sck)]
     64 	set sendid [::ts6::b64e $uid]
     65 	set sendnn [string repeat "A" [expr {6-[string length $sendid]}]]
     66 	append sendnn $sendid
     67 	putdcc $sck [format ":%s%s TOPIC %s :%s" $sid $sendnn $targ $topic]
     68 }
     69 
     70 proc ::ts6::setnick {sck uid newnick} {
     71 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]]
     72 	append sid [::ts6::b64e $::sid($sck)]
     73 	set sendid [::ts6::b64e $uid]
     74 	set sendnn [string repeat "A" [expr {6-[string length $sendid]}]]
     75 	append sendnn $sendid
     76 	putdcc $sck [format ":%s%s NICK %s :%s" $sid $sendnn $newnick [clock format [clock seconds] -format %s]]
     77 }
     78 
     79 proc ::ts6::sethost {sck targ topic} {
     80 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]]
     81 	append sid [::ts6::b64e $::sid($sck)]
     82 	if {![tnda get "ts6/$::netname($sck)/euid"]} {
     83 		putdcc $sck [format ":%s ENCAP * CHGHOST %s %s" $sid $targ $topic]
     84 	} {
     85 		putdcc $sck [format ":%s CHGHOST %s %s" $sid $targ $topic]
     86 	}
     87 }
     88 
     89 proc ::ts6::sendSid {sck sname sid {realname "In use by Services"}} {
     90 set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]]
     91 append sid [::ts6::b64e $::sid($sck)]
     92 	set sl [format ":%s SID %s 1 %s :%s" [::ts6::b64e $sid] $sname [::ts6::b64e $sid] $realname]
     93 	putdcc $sck $sl
     94 }
     95 
     96 proc ::ts6::privmsg {sck uid targ msg} {
     97 set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]]
     98 append sid [::ts6::b64e $::sid($sck)]
     99 	set sendid [::ts6::b64e $uid]
    100 	set sendnn [string repeat "A" [expr {6-[string length $sendid]}]]
    101 	append sendnn $sendid
    102 	putdcc $sck [format ":%s%s PRIVMSG %s :%s" $sid $sendnn $targ $msg]
    103 }
    104 
    105 proc ::ts6::metadata {sck targ direction type {msg ""}} {
    106 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]]
    107 	append sid [::ts6::b64e $::sid($sck)]
    108 	if {[string toupper $direction] != "ADD" && [string toupper $direction] != "DELETE"} {putcmdlog "failed METADATA attempt (invalid arguments)";return} ;#no that didn't work
    109 	if {[string toupper $direction] == "ADD"} {
    110 		tnda set "metadata/$::netname($sck)/$targ/[ndaenc $type]" $msg
    111 		putdcc $sck [format ":%s ENCAP * METADATA %s %s %s :%s" $sid [string toupper $direction] $targ [string toupper $type] $msg]
    112 	}
    113 	if {[string toupper $direction] == "DELETE"} {
    114 		tnda set "metadata/$::netname($sck)/$targ/[ndaenc $type]" ""
    115 		putdcc $sck [format ":%s ENCAP * METADATA %s %s :%s" $sid [string toupper $direction] $targ [string toupper $type]]
    116 	}
    117 }
    118 
    119 proc ::ts6::kick {sck uid targ tn msg} {
    120 set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]]
    121 append sid [::ts6::b64e $::sid($sck)]
    122 	set sendid [::ts6::b64e $uid]
    123 	set sendnn [string repeat "A" [expr {6-[string length $sendid]}]]
    124 	append sendnn $sendid
    125 	putdcc $sck [format ":%s%s KICK %s %s :%s" $sid $sendnn $targ $tn $msg]
    126 }
    127 
    128 proc ::ts6::notice {sck uid targ msg} {
    129 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]];append sid [::ts6::b64e $::sid($sck)]
    130 	set sendid [::ts6::b64e $uid]
    131 	set sendnn [string repeat "A" [expr {6-[string length $sendid]}]]
    132 	append sendnn $sendid
    133 	putdcc $sck [format ":%s%s NOTICE %s :%s" $sid $sendnn $targ $msg]
    134 }
    135 
    136 proc ::ts6::part {sck uid targ msg} {
    137 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]];append sid [::ts6::b64e $::sid($sck)]
    138 	set sendid [::ts6::b64e $uid]
    139 	set sendnn [string repeat "A" [expr {6-[string length $sendid]}]]
    140 	append sendnn $sendid
    141 	putdcc $sck [format ":%s%s PART %s :%s" $sid $sendnn $targ $msg]
    142 }
    143 
    144 proc ::ts6::quit {sck uid msg} {
    145 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]];append sid [::ts6::b64e $::sid($sck)]
    146 	set sendid [::ts6::b64e $uid]
    147 	set sendnn [string repeat "A" [expr {6-[string length $sendid]}]]
    148 	append sendnn $sendid
    149 	putdcc $sck [format ":%s%s QUIT :%s" $sid $sendnn $msg]
    150 	tnda set "intclient/$::netname($sck)/${sid}${sendnn}" ""
    151 	tnda set "nick/$::netname($sck)/${sid}${sendnn}" ""
    152 }
    153 
    154 proc ::ts6::setacct {sck targ msg} {
    155 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]];append sid [::ts6::b64e $::sid($sck)]
    156 	putdcc $sck [format ":%s ENCAP * SU %s %s" $sid $targ $msg]
    157 	tnda set "login/$::netname($sck)/$targ" $msg
    158 }
    159 
    160 proc ::ts6::putmotd {sck targ msg} {
    161 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]];append sid [::ts6::b64e $::sid($sck)]
    162 	putdcc $sck [format ":%s 372 %s :- %s" $sid $targ $msg]
    163 }
    164 
    165 proc ::ts6::putmotdend {sck targ} {
    166 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]];append sid [::ts6::b64e $::sid($sck)]
    167 	putdcc $sck [format ":%s 376 %s :End of global MOTD." $sid $targ]
    168 }
    169 
    170 proc ::ts6::putmode {sck uid targ mode parm ts} {
    171 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]];append sid [::ts6::b64e $::sid($sck)]
    172 	set sendid [::ts6::b64e $uid]
    173 	set sendnn [string repeat "A" [expr {6-[string length $sendid]}]]
    174 	append sendnn $sendid
    175 	putdcc $sck [format ":%s%s TMODE %s %s %s %s" $sid $sendnn $ts $targ $mode $parm]
    176 }
    177 
    178 proc ::ts6::putjoin {sck uid targ ts} {
    179 	set sid [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]];append sid [::ts6::b64e $::sid($sck)]
    180 	set sendid [::ts6::b64e $uid]
    181 	set sendnn [string repeat "A" [expr {6-[string length $sendid]}]]
    182 	append sendnn $sendid
    183 	putdcc $sck [format ":%s SJOIN %s %s + :%s%s" $sid $ts $targ $sid $sendnn]
    184 }
    185 
    186 proc ::ts6::irc-main {sck} {
    187 	global sid sock
    188 	if {[eof $sck]} {close $sck}
    189 	gets $sck line
    190 	set line [string trim $line "\r\n"]
    191 	set one [string match ":*" $line]
    192 	set line [string trimleft $line ":"]
    193 	set gotsplitwhere [string first " :" $line]
    194 	if {$gotsplitwhere==-1} {set comd [split $line " "]} {set comd [split [string range $line 0 [expr {$gotsplitwhere - 1}]] " "]}
    195 	set payload [split [string range $line [expr {$gotsplitwhere + 2}] end] " "]
    196 	#putcmdlog [join $comd " "]
    197 	if {[lindex $comd 0] == "PING"} {putdcc $sck "PONG $::servername :$payload"}
    198 	if {[lindex $comd 0] == "SERVER"} {putdcc $sck "VERSION"}
    199 	switch -nocase -- [lindex $comd $one] {
    200 		"479" {putcmdlog $payload}
    201 
    202 		"005" {
    203 			foreach {tok} [lrange $comd 3 end] {
    204 				foreach {key val} [split $tok "="] {
    205 					if {$key == "PREFIX"} {
    206 						# We're in luck! Server advertises its PREFIX in VERSION reply to servers.
    207 						set v [string range $val 1 end]
    208 						set mod [split $v ")"]
    209 						set modechar [split [lindex $mod 1] {}]
    210 						set modepref [split [lindex $mod 0] {}]
    211 						foreach {c} $modechar {x} $modepref {
    212 							nda set "ts6/$::netname($sck)/prefix/$c" $x
    213 						}
    214 						foreach {x} $modechar {c} $modepref {
    215 							nda set "ts6/$::netname($sck)/pfxchar/$c" $x
    216 						}
    217 						putcmdlog [nda get "ts6/$::netname($sck)/prefix"]
    218 						putcmdlog [nda get "ts6/$::netname($sck)/pfxchar"]
    219 					}
    220 				}
    221 			}
    222 		}
    223 
    224 		"PRIVMSG" {
    225 			if {[string index [lindex $comd 2] 0] == "#" || [string index [lindex $comd 2] 0] == "&" || [string index [lindex $comd 2] 0] == "!" || [string index [lindex $comd 2] 0] == "+" || [string index [lindex $comd 2] 0] == "."} {
    226 				set client chan
    227 				callbind $sck pub "-" [string tolower [lindex $payload 0]] [lindex $comd 2] [lindex $comd 0] [lrange $payload 1 end]
    228 				callbind $sck evnt "-" "chanmsg" [lindex $comd 0] [lindex $comd 2] [lrange $payload 0 end]
    229 			} {
    230 				set client [tnda get "intclient/$::netname($sck)/[lindex $comd 2]"]
    231 				callbind $sck msg $client [string tolower [lindex $payload 0]] [lindex $comd 0] [lrange $payload 1 end]
    232 				callbind $sck "evnt" "-" "privmsg" [lindex $comd 0] [lindex $comd 2] [lrange $payload 0 end]
    233 			}
    234 		}
    235 
    236 		"NOTICE" {
    237 			if {![tnda get "ts6/$::netname($sck)/connected"]} {return}
    238 			if {[string index [lindex $comd 2] 0] == "#" || [string index [lindex $comd 2] 0] == "&" || [string index [lindex $comd 2] 0] == "!" || [string index [lindex $comd 2] 0] == "+" || [string index [lindex $comd 2] 0] == "."} {
    239 				set client chan
    240 				callbind $sck pubnotc "-" [string tolower [lindex $payload 0]] [lindex $comd 2] [lindex $comd 0] [lrange $payload 1 end]
    241 				callbind $sck pubnotc-m "-" [string tolower [lindex $payload 0]] [lindex $comd 2] [lindex $comd 0] [lrange $payload 1 end]
    242 				callbind $sck "evnt" "-" "channotc" [lindex $comd 0] [lindex $comd 2] [lrange $payload 0 end]
    243 			} {
    244 				set client [tnda get "intclient/$::netname($sck)/[lindex $comd 2]"]
    245 				callbind $sck notc $client [string tolower [lindex $payload 0]] [lindex $comd 0] [lrange $payload 1 end]
    246 				callbind $sck "evnt" "-" "privnotc" [lindex $comd 0] [lindex $comd 2] [lrange $payload 0 end]
    247 			}
    248 		}
    249 
    250 		"MODE" {
    251 			if {[lindex $comd 3] == [tnda get "nick/$::netname($sck)/[lindex $comd 0]"]} {
    252 				foreach {c} [split [lindex $comd 4] {}] {
    253 					switch -- $c {
    254 						"+" {set state 1}
    255 						"-" {set state 0}
    256 						"o" {tnda set "oper/$::netname($sck)/[lindex $comd 0]" $state}
    257 					}
    258 				}
    259 			}
    260 		}
    261 
    262 		"JOIN" {
    263 			set chan [string map {/ [} [::base64::encode [string tolower [lindex $comd 3]]]]
    264 			if {""==[tnda get "channels/$::netname($sck)/$chan/ts"]} {callbind $sck create "-" "-" [lindex $comd 3] [lindex $comd 0] $::netname($sck)}
    265 			callbind $sck join "-" "-" [lindex $comd 3] [lindex $comd 0] $::netname($sck)
    266 			tnda set "channels/$::netname($sck)/$chan/ts" [lindex $comd 2]
    267 			tnda set "userchan/$::netname($sck)/[lindex $comd 0]/$chan" 1
    268 		}
    269 
    270 		"TMODE" {
    271 			set ctr 4
    272 			set state 1
    273 			foreach {c} [split [lindex $comd 4] {}] {
    274 				switch -regexp -- $c {
    275 					"\\\+" {set state 1}
    276 					"-" {set state 0}
    277 					"[ABCcDdiMmNnOpPQRrSsTtZz]" {callbind $sck mode "-" [expr {$state ? "+" : "-"}] $c [lindex $comd 0] [lindex $comd 3] "" $::netname($sck)}
    278 					"[beljfxqIaykohv]" {callbind $sck mode "-" [expr {$state ? "+" : "-"}] $c [lindex $comd 0] [lindex $comd 3] [lindex $comd [incr ctr]] $::netname($sck)}
    279 				}
    280 			}
    281 		}
    282 
    283 		"SJOIN" {
    284 			set chan [string map {/ [} [::base64::encode [string tolower [lindex $comd 3]]]]
    285 			if {[string index [lindex $comd 4] 0] == "+"} {
    286 				set four 5
    287 				if {[string match "*l*" [lindex $comd 4]]} {incr four}
    288 				if {[string match "*f*" [lindex $comd 4]]} {incr four}
    289 				if {[string match "*j*" [lindex $comd 4]]} {incr four}
    290 				if {[string match "*k*" [lindex $comd 4]]} {incr four}
    291 			} {
    292 				set four 4
    293 			}
    294 			tnda set "channels/$::netname($sck)/$chan/ts" [lindex $comd 2]
    295 			foreach {nick} $payload {
    296 				set un ""
    297 				set uo ""
    298 				set state uo
    299 				foreach {c} [split $nick {}] {
    300 					if {[string is integer $c]} {set state un}
    301 					if {$state == "uo"} {set c [nda get "ts6/$::netname($sck)/pfxchar/$c"] ; }
    302 					if {"un"==$state} {append un $c}
    303 					if {"uo"==$state} {append uo $c}
    304 				}
    305 				callbind $sck join "-" "-" [lindex $comd 3] $un $::netname($sck)
    306 						putcmdlog "$un+$uo"
    307 				if {""!=$uo} {tnda set "channels/$::netname($sck)/$chan/modes/$un" $uo
    308 					foreach {c} [split $uo {}] {
    309 						putcmdlog "$un+$c"
    310 						callbind $sck mode "-" + $c $un [lindex $comd 3] $un $::netname($sck)
    311 					}
    312 				}
    313 			}
    314 
    315 		}
    316 
    317 		"PART" {
    318 			callbind $sck part "-" "-" [lindex $comd 2] [lindex $comd 0] $::netname($sck)
    319 			set chan [string map {/ [} [::base64::encode [string tolower [lindex $comd 2]]]]
    320 			tnda set "userchan/$::netname($sck)/[lindex $comd 0]/$chan" 0
    321 		}
    322 
    323 		"KICK" {
    324 			callbind $sck part "-" "-" [lindex $comd 2] [lindex $comd 3] $::netname($sck)
    325 		}
    326 
    327 		"NICK" {
    328 			tnda set "nick/$::netname($sck)/[lindex $comd 0]" [lindex $comd 2]
    329 		}
    330 
    331 		"EUID" {
    332 			set num 9
    333 			set ctr 1
    334 			set oper 0
    335 			set loggedin [lindex $comd 11]
    336 			set realhost [lindex $comd 10]
    337 			set modes [lindex $comd 4]
    338 			if {[string match "*o*" $modes]} {set oper 1}
    339 			if {"*"!=$loggedin} {
    340 				tnda set "login/$::netname($sck)/[lindex $comd $num]" $loggedin
    341 			}
    342 			if {"*"!=$realhost} {
    343 				tnda set "rhost/$::netname($sck)/[lindex $comd $num]" $realhost
    344 			} {
    345 				tnda set "rhost/$::netname($sck)/[lindex $comd $num]" [lindex $comd 7]
    346 			}
    347 			tnda set "nick/$::netname($sck)/[lindex $comd $num]" [lindex $comd 2]
    348 			tnda set "oper/$::netname($sck)/[lindex $comd $num]" $oper
    349 			tnda set "ident/$::netname($sck)/[lindex $comd $num]" [lindex $comd 6]
    350 			tnda set "vhost/$::netname($sck)/[lindex $comd $num]" [lindex $comd 7]
    351 			tnda set "rname/$::netname($sck)/[lindex $comd $num]" $payload
    352 			putcmdlog "New user at $::netname($sck) [lindex $comd $num] [lindex $comd 2]![lindex $comd 6]@[tnda get "rhost/$::netname($sck)/[lindex $comd $num]"] (vhost [tnda get "vhost/$::netname($sck)/[lindex $comd $num]"]) :$payload"
    353 			callbind $sck conn "-" "-" [lindex $comd $num]
    354 		}
    355 
    356 		"ENCAP" {
    357 			putcmdlog [join [list $comd "--" $payload] " "]
    358 			switch -nocase -- [lindex $comd 3] {
    359 				"SASL" {
    360 					#don't bother
    361 				}
    362 				"SU" {
    363 					if {$payload == ""} {set payload [lindex $comd 5]}
    364 					tnda set "login/$::netname($sck)/[lindex $comd 4]" $payload
    365 					if {$payload == ""} {callbind $sck logout "-" "-" [lindex $comd 4]} {callbind $sck login "-" "-" [lindex $comd 4] $payload}
    366 				}
    367 				"CERTFP" {
    368 					tnda set "certfps/$::netname($sck)/[lindex $comd 0]" $payload
    369 					callbind $sck encap "-" "certfp" [lindex $comd 0] $payload
    370 				}
    371 				"METADATA" {
    372 					switch -nocase -- [lindex $comd 4] {
    373 						"ADD" {
    374 							tnda set "metadata/$::netname($sck)/[lindex $comd 5]/[ndaenc [lindex $comd 6]]" $payload
    375 							callbind $sck encap "-" "metadata.[string tolower [lindex $comd 6]]" [lindex $comd 5] $payload
    376 						}
    377 						"DELETE" {
    378 							tnda set "metadata/$::netname($sck)/[lindex $comd 5]/[ndaenc $payload]" ""
    379 							callbind $sck encap "-" "metadata.[string tolower $payload]" [lindex $comd 5] ""
    380 						}
    381 					}
    382 				}
    383 			}
    384 		}
    385 
    386 		"TOPIC" {
    387 			callbind $sck topic "-" "-" [lindex $comd 2] [join $payload " "]
    388 		}
    389 		"QUIT" {
    390 			if {![string is digit [string index [lindex $comd 0] 0]]} {
    391 				set ocomd [lrange $comd 1 end]
    392 				set on [lindex $comd 0]
    393 				set comd [list [::ts6::nick2uid $::netname($sck) $on] {*}$ocomd]
    394 				putcmdlog "Uh-oh, netsplit! $on -> [::ts6::nick2uid $::netname($sck) $on] has split"
    395 			}
    396 			foreach {chan _} [tnda get "userchan/$::netname($sck)/[lindex $comd 0]"] {
    397 				callbind $sck part "-" "-" [ndadec $chan] [lindex $comd 0] $::netname($sck)
    398 				tnda set "userchan/$::netname($sck)/[lindex $comd 0]/$chan" 0
    399 			}
    400 
    401 			tnda set "login/$::netname($sck)/[lindex $comd 0]" ""
    402 			tnda set "nick/$::netname($sck)/[lindex $comd 0]" ""
    403 			tnda set "oper/$::netname($sck)/[lindex $comd 0]" 0
    404 			tnda set "ident/$::netname($sck)/[lindex $comd 0]" ""
    405 			tnda set "rhost/$::netname($sck)/[lindex $comd 0]" ""
    406 			tnda set "vhost/$::netname($sck)/[lindex $comd 0]" ""
    407 			tnda set "rname/$::netname($sck)/[lindex $comd 0]" ""
    408 			tnda set "metadata/$::netname($sck)/[lindex $comd 0]" [list]
    409 			tnda set "certfps/$::netname($sck)/[lindex $comd 0]" ""
    410 			callbind $sck quit "-" "-" [lindex $comd 0] $::netname($sck)
    411 		}
    412 
    413 		"KILL" {
    414 			foreach {chan _} [tnda get "userchan/$::netname($sck)/[lindex $comd 2]"] {
    415 				callbind $sck part "-" "-" [ndadec $chan] [lindex $comd 2]
    416 				tnda set "userchan/$::netname($sck)/[lindex $comd 2]/$chan" 0
    417 			}
    418 			tnda set "login/$::netname($sck)/[lindex $comd 2]" ""
    419 			tnda set "nick/$::netname($sck)/[lindex $comd 2]" ""
    420 			tnda set "oper/$::netname($sck)/[lindex $comd 2]" 0
    421 			tnda set "ident/$::netname($sck)/[lindex $comd 2]" ""
    422 			tnda set "rhost/$::netname($sck)/[lindex $comd 2]" ""
    423 			tnda set "vhost/$::netname($sck)/[lindex $comd 2]" ""
    424 			tnda set "rname/$::netname($sck)/[lindex $comd 2]" ""
    425 			tnda set "metadata/$::netname($sck)/[lindex $comd 2]" [list]
    426 			tnda set "certfps/$::netname($sck)/[lindex $comd 2]" ""
    427 		}
    428 
    429 		"ERROR" {
    430 			putcmdlog "Recv'd an ERROR $payload from $::netname($sck)"
    431 		}
    432 
    433 		"CAPAB" {
    434 			tnda set "ts6/$::netname($sck)/euid" 0
    435 			foreach {cw} [split $payload " "] {
    436 				if {$cw == "EUID"} {tnda set "ts6/$::netname($sck)/euid" 1}
    437 			}
    438 			tnda set "ts6/$::netname($sck)/connected" 1
    439 		}
    440 
    441 		"PING" {
    442 			set num [string repeat "0" [expr {3-[string length [::ts6::b64e $::sid($sck)]]}]]
    443 			append num [::ts6::b64e $::sid($sck)]
    444 			if {[lindex $comd 3]==""} {set pong [lindex $comd 0]} {set pong [lindex $comd 3]}
    445 			putdcc $sck ":$num PONG $pong [lindex $comd 2]"
    446 		}
    447 	}
    448 }
    449 
    450 proc ::ts6::login {sck {osid "42"} {password "link"} {servname "net"}} {
    451 	set num [string repeat "0" [expr {3-[string length [::ts6::b64e $osid]]}]]
    452 	append num [::ts6::b64e $osid]
    453 	global netname sid sock nettype
    454 	set netname($sck) $servname
    455 	set nettype($servname) ts6
    456 	set sock($servname) $sck
    457 	set sid($sck) $osid
    458 	set sid($servname) $osid
    459 	tnda set "ts6/$::netname($sck)/connected" 0
    460 	tnda set "ts6/$::netname($sck)/euid" 0
    461 	if {![info exists ::ts6(halfops)]} {tnda set "pfx/halfop" v} {tnda set "pfx/halfop" $::ts6(halfops)}
    462 	if {![info exists ::ts6(ownermode)]} {tnda set "pfx/owner" o} {tnda set "pfx/owner" $::ts6(ownermode)}
    463 	if {![info exists ::ts6(protectmode)]} {tnda set "pfx/protect" o} {tnda set "pfx/protect" $::ts6(protectmode)}
    464 	if {![info exists ::ts6(euid)]} {set ::ts6(euid) 1}
    465 	putdcc $sck "PASS $password TS 6 :$num"
    466 	putdcc $sck "CAPAB :EUID ENCAP IE EX CLUSTER EOPMOD SVS SERVICES"
    467 	putdcc $sck "SERVER $::servername 1 :chary.tcl for Eggdrop and related bots"
    468 	putdcc $sck "SVINFO 6 6 0 :[clock format [clock seconds] -format %s]"
    469 	putdcc $sck ":$num VERSION"
    470 	bind $sck mode - + ::ts6::checkop
    471 	bind $sck mode - - ::ts6::checkdeop
    472 }
    473 
    474 #source services.conf
    475 
    476 proc ::ts6::nick2uid {netname nick} {
    477 	foreach {u n} [tnda get "nick/$netname"] {
    478 		if {[string tolower $n] == [string tolower $nick]} {return $u}
    479 	}
    480 }
    481 proc ::ts6::intclient2uid {netname nick} {
    482 	foreach {u n} [tnda get "intclient/$netname"] {
    483 		if {[string tolower $n] == [string tolower $nick]} {return $u}
    484 	}
    485 }
    486 proc ::ts6::uid2nick {netname u} {
    487 	return [tnda get "nick/$netname/$u"]
    488 }
    489 proc ::ts6::uid2rhost {netname u} {
    490 	return [tnda get "rhost/$netname/$u"]
    491 }
    492 proc ::ts6::uid2host {netname u} {
    493 	return [tnda get "host/$netname/$u"]
    494 }
    495 proc ::ts6::uid2ident {netname u} {
    496 	return [tnda get "ident/$netname/$u"]
    497 }
    498 proc ::ts6::nick2host {netname nick} {
    499 	return [tnda get "host/$netname/[nick2uid $netname $nick]"]
    500 }
    501 proc ::ts6::nick2ident {netname nick} {
    502 	return [tnda get "ident/$netname/[nick2uid $netname $nick]"]
    503 }
    504 proc ::ts6::nick2rhost {netname nick} {
    505 	return [tnda get "rhost/$netname/[nick2uid $netname $nick]"]
    506 }
    507 proc ::ts6::getts {netname chan} {
    508 	return [tnda get "channels/$netname/[ndaenc $chan]/ts"]
    509 }
    510 proc ::ts6::getpfx {netname chan nick} {
    511 	return [tnda get "channels/$netname/[ndaenc $chan]/modes/[::ts6::nick2uid $netname $nick]"]
    512 }
    513 proc ::ts6::getupfx {netname chan u} {
    514 	return [tnda get "channels/$netname/[ndaenc $chan]/modes/$u"]
    515 }
    516 proc ::ts6::getpfxchars {netname modes} {
    517 	set o ""
    518 	foreach {c} [split $modes {}] {
    519 		append o [nda get "ts6/$netname/prefix/$c"]
    520 	}
    521 	return $o
    522 }
    523 proc ::ts6::getmetadata {netname nick metadatum} {
    524 	return [tnda get "metadata/$netname/[::ts6::nick2uid $netname $nick]/[ndaenc $metadatum]"]
    525 }
    526 proc ::ts6::getcertfp {netname nick} {
    527 	return [tnda get "certfps/$netname/[::ts6::nick2uid $netname $nick]"]
    528 }
    529 
    530 proc ::ts6::checkop {mc ftp} {
    531 	set f [lindex $ftp 0]
    532 	set t [lindex $ftp 1]
    533 	set p [lindex $ftp 2]
    534 	set n [lindex $ftp 3]
    535 	if {[nda get "ts6/$n/pfxchar/$mc"]==""} {return}
    536 putcmdlog "up $mc $f $t $p $n"
    537   set chan [string map {/ [} [::base64::encode [string tolower $t]]]
    538   tnda set "channels/$n/$chan/modes/$p" "[string map [list $mc ""] [tnda get "channels/$n/$chan/modes/$p"]]$mc"
    539 }
    540 
    541 proc ::ts6::checkdeop {mc ftp} {
    542 	set f [lindex $ftp 0]
    543 	set t [lindex $ftp 1]
    544 	set p [lindex $ftp 2]
    545 	set n [lindex $ftp 3]
    546 	if {[nda get "ts6/$n/pfxchar/$mc"]==""} {return}
    547 putcmdlog "down $mc $f $t $p $n"
    548   set chan [string map {/ [} [::base64::encode [string tolower $t]]]
    549   tnda set "channels/$n/$chan/modes/$p" "[string map [list $mc ""] [tnda get "channels/$n/$chan/modes/$p"]]"
    550 }
    551 
    552 proc ::ts6::getfreeuid {net} {
    553 set work 1
    554 set cns [list]
    555 foreach {_ cnum} [tnda get "intclient/$net"] {lappend cns $cnum}
    556 while {0!=$work} {set num [expr {[rand 300000]+10000}];if {[lsearch -exact $cns $num]==-1} {set work 0}}
    557 return $num
    558 }
    559 
    560 namespace export *
    561 namespace ensemble create
    562 }
    563 
    564 #ts6 login $::sock