]> jfr.im git - irc/grawity/eggdrop-ts6.git/blame - g_ts6.tcl
case-insensitive nick handling where apropriate
[irc/grawity/eggdrop-ts6.git] / g_ts6.tcl
CommitLineData
331ad8b6
MM
1# vim: ts=4:sw=4
2#
640024b7
MM
3set myserv "fallen.sky"
4set mysid "1EG"
331ad8b6
MM
5
6## misc util functions
7
8proc chanref:join {hand} {
9 global members
10 expr {[incr members($hand)] == 1}
11}
12
13proc chanref:part {hand} {
14 global members
15 expr {[incr members($hand) -1] == 0}
16}
17
18proc chanref:rename {oldhand newhand} {
19 global members
20 set count $members($oldhand)
21 set members($newhand) $count
22 set members($oldhand) 0
23 return $count
24}
25
26proc chanref:quit {hand} {
27 global members
28 set count $members($hand)
29 set members($hand) 0
30 return $count
31}
32
33proc lshift listVar {
34 upvar 1 $listVar l
35 set r [lindex $l 0]
36 set l [lreplace $l [set l 0] 0]
37 return $r
38}
39
40array unset baseary
41array set baseary {
42 0 A 1 B 2 C 3 D 4 E 5 F 6 G 7 H 8 I 9 J
deb2267d 43 10 K 11 L 12 M 13 N 14 O 15 P 16 Q 17 R 18 S 19 T
331ad8b6
MM
44 20 U 21 V 22 W 23 X 24 Y 25 Z 26 0 27 1 28 2 29 3
45 30 4 31 5 32 6 33 7 34 8 35 9
46}
47
48proc ts6:nextuid {} {
331ad8b6 49 global baseary
640024b7
MM
50 global mysid
51 global ts6-uidcounter
52
331ad8b6
MM
53 set num [incr ts6-uidcounter]
54 set rad 0
55 set val 1
56 while {$num > $val} { set val [expr {pow(36,[incr rad])}] }
57 set result ""
58 while {$num > 0} {
59 set pow [expr {int(pow(36,$rad))}]
60 set red [expr {int($num/$pow)}]
61 incr num [expr {-($pow*$red)}]
62 append result $baseary($red)
63 incr rad -1
64 }
65 incr rad
66 while {$rad} {
67 append result A
68 incr rad -1
69 }
70 set pad [string repeat A [expr {6 - [string length $result]}]]
640024b7 71 set uid $mysid$pad$result
331ad8b6
MM
72 return $uid
73}
74
75proc getflag {hand} {
76 return [expr {[matchattr $hand +o] ? "@" : ""}]
77}
78
2d9c1b72
MM
79proc nicktolower {nick} {
80 string map {{[} \{ \\ | \] \}} [string tolower $nick]
81}
82
331ad8b6
MM
83## ts6 database functions
84
85proc ts6:myuid {uid} {
640024b7
MM
86 global mysid
87
88 return [string match "$mysid*" $uid]
89}
90
91proc ts6:hand2nick {hand} {
92 return "0|$hand"
93}
94
95proc ts6:nick2hand {nick} {
96 if {[string match "0|*" $nick]} {
97 return [string range $nick 2 end]
98 }
99 return ""
331ad8b6
MM
100}
101
102proc ts6:nick2uid {nick} {
103 global nick2uid
2d9c1b72
MM
104 set nick [nicktolower $nick]
105 if {[info exists nick2uid($nick)]} {
106 return $nick2uid($nick)
107 }
108 return ""
109}
110
111proc ts6:ownnick2uid {nick} {
112 global nick2uid
113 set nick [nicktolower $nick]
331ad8b6
MM
114 if {[info exists nick2uid($nick)]} {
115 return $nick2uid($nick)
116 }
117 set uid [ts6:nextuid]
118 set nick2uid($nick) $uid
119 return $uid
120}
121
640024b7 122proc ts6:uid2nick {uid} {
c3bec97d 123 uid:get $uid NICK $uid
331ad8b6
MM
124}
125
640024b7
MM
126proc ts6:serv2sid {serv} {
127 global serv2sid
128 if {[info exists serv2sid($serv)]} {
129 return $serv2sid($serv)
331ad8b6 130 }
640024b7 131 return $serv
331ad8b6 132}
640024b7
MM
133
134proc ts6:sid2serv {sid} {
135 global sid2serv
136 if {[info exists sid2serv($sid)]} {
137 return [lindex $sid2serv($sid) 0]
138 }
139 return $sid
140}
141
142proc ts6:id2name {id} {
143 switch [string length $id] {
3db4fdad
MM
144 3 { ts6:sid2serv $id }
145 9 { ts6:uid2nick $id }
640024b7 146 * { return $id }
331ad8b6 147 }
331ad8b6
MM
148}
149
150proc ts6:changed-nick {oldnick newnick} {
151 global nick2uid
331ad8b6
MM
152
153 set uid [ts6:nick2uid $oldnick]
331ad8b6 154
c3bec97d 155 uid:set $uid NICK $newnick
2d9c1b72
MM
156
157 set newnick [nicktolower $newnick]
158 set oldnick [nicktolower $oldnick]
159
160 set nick2uid($newnick) $uid
161 unset nick2uid($oldnick)
331ad8b6
MM
162}
163
3db4fdad
MM
164proc uid:set {uid key val} {
165 global uidinfo
166 dict set uidinfo($uid) $key $val
167}
168
169proc uid:get {uid key {def ""}} {
170 global uidinfo
c3bec97d
MM
171 if {[info exists uidinfo($uid)] &&
172 [dict exists $uidinfo($uid) $key]} {
3db4fdad
MM
173 dict get $uidinfo($uid) $key
174 } else {
175 return $def
176 }
177}
178
331ad8b6
MM
179## server functions
180
181proc ts6:put {msg} {
182 global ts6-idx
183 putlog "output: $msg"
184 putdcc ${ts6-idx} $msg
185}
186
187proc ts6:sput {msg} {
640024b7
MM
188 global mysid
189 ts6:put ":$mysid $msg"
331ad8b6
MM
190}
191
192proc ts6:cput {msg} {
640024b7 193 global ts6-mynick
2d9c1b72 194 ts6:put ":[ts6:ownnick2uid ${ts6-mynick}] $msg"
331ad8b6
MM
195}
196
197proc ts6:introduce {hand} {
331ad8b6 198 global botnet-nick
640024b7
MM
199 global ts6-introduced
200 global ts6-mynick
640024b7
MM
201 global uptime
202
331ad8b6 203 set nick [ts6:hand2nick $hand]
2d9c1b72 204 set uid [ts6:ownnick2uid $nick]
331ad8b6 205 if {![info exists ts6-introduced($uid)]} {
c3bec97d
MM
206 uid:set $uid NICK $nick
207 ts6:sput "UID $nick 1 $uptime +i $hand ${botnet-nick} ${botnet-nick} $uid :$hand"
331ad8b6
MM
208 set ts6-introduced($uid) $uid
209 }
210 return $uid
211}
212
213proc ts6:connect {host port} {
640024b7
MM
214 global botnet-nick
215 global myserv
216 global mysid
217 global nick2uid
218 global serv2sid
219 global sid2serv
220 global ts6-idx
221 global ts6-introduced
222 global ts6-mynick
223 global ts6-uidcounter
224 global uidinfo
640024b7 225 global uptime
331ad8b6
MM
226
227 set idx [connect $host $port]
228
229 array unset nick2uid *
640024b7
MM
230 array unset uidinfo *
231 array unset serv2sid *
232 array unset sid2serv *
331ad8b6
MM
233 array unset ts6-introduced *
234 set ts6-idx $idx
331ad8b6 235 set ts6-uidcounter 0
640024b7
MM
236 set ts6-mynick "\[${botnet-nick}\]"
237
2d9c1b72 238 set myuid [ts6:ownnick2uid ${ts6-mynick}]
331ad8b6 239
640024b7
MM
240 set serv2sid($myserv) $mysid
241 set sid2serv($mysid) [list $myserv 0 "Eggdrop pseudoserver"]
331ad8b6 242
640024b7 243 putdcc $idx "PASS jilles TS 6 :$mysid"
3db4fdad 244 putdcc $idx "CAPAB :ENCAP EUID QS SERVICES TB"
640024b7 245 putdcc $idx "SERVER $myserv 0 :Eggdrop pseudoserver"
c3bec97d
MM
246 uid:set $myuid NICK ${ts6-mynick}
247 ts6:sput "UID ${ts6-mynick} 1 $uptime +Sio ${botnet-nick} huh huh $myuid :${botnet-nick} (bot)"
331ad8b6
MM
248
249 array unset skip
250 set sjoin "@$myuid"
251 foreach sub [whom 0] {
252 set hand [lindex $sub 0]
253 set flag [lindex $sub 3]
254 if {![info exists skip($hand)]} {
255 set skip($hand) 1
256 set uid [ts6:introduce $hand]
640024b7 257 set prefix [expr {$flag == "" ? "" : "+"}]
331ad8b6
MM
258 lappend sjoin $prefix$uid
259 }
260 }
261
640024b7
MM
262 ts6:sput "SJOIN $uptime #partyline +nt :$sjoin"
263 ts6:sput "TB #partyline $uptime ${ts6-mynick} :Direct link to ${ts6-mynick}'s partyline channel"
264
265 ts6:sput "SJOIN [unixtime] #nullroute + :$sjoin"
331ad8b6
MM
266
267 control $idx ts6:handshake
268}
269
270proc ts6:handshake {idx input} {
271 global ts6-capab
640024b7 272 global ts6-mynick
c3bec97d 273 global nick2uid uidinfo
640024b7
MM
274 global serv2sid sid2serv
275 global mysid
331ad8b6
MM
276
277 set input [rparse $input]
278 putlog "input{$idx} $input"
279 set prefix ""
280 set cmd [lindex $input 0]
281 if {[string index $cmd 0] == ":"} {
282 set prefix [string range [lshift input] 1 end]
283 set cmd [lindex $input 0]
284 }
285 switch [lindex $input 0] {
286 CAPAB {
287 lappend ts6-capab {*}[lindex $input 1]
288 }
640024b7
MM
289 ENCAP {
290 set mask [lindex $input 1]
291 set input [lrange $input 2 end]
292
293 if {$mask == "*" || $mask == $myserv} {
294 switch [lindex $input 0] {
3db4fdad
MM
295 CERTFP { uid:set $prefix FPRINT [lindex $input 1] }
296 LOGIN { uid:set $prefix LOGIN [lindex $input 1] }
297 SU {
298 set uid [lindex $input 1]
299 set login [lindex $input 2]
300 if {$login == ""} {set login "*"}
301 uid:set $uid LOGIN $login
640024b7
MM
302 }
303 }
304 }
305 }
3db4fdad 306 EUID {
2d9c1b72 307 set nick [nicktolower [lindex $input 1]]
3db4fdad
MM
308 set uid [lindex $input 8]
309
3db4fdad
MM
310 set nick2uid($nick) $uid
311
c3bec97d 312 uid:set $uid NICK [lindex $input 1]
3db4fdad
MM
313 uid:set $uid USERNAME [lindex $input 5]
314 uid:set $uid HOSTNAME [lindex $input 6]
315 uid:set $uid LOGIN [lindex $input 10]
316 uid:set $uid REALNAME [lindex $input 11]
317 }
331ad8b6
MM
318 JOIN {
319 set nick [ts6:uid2nick $prefix]
320 }
321 KILL {
322 set victimuid [lindex $input 1]
323 set victimnick [ts6:uid2nick $victimuid]
324 set victimhand [ts6:nick2hand $victimnick]
325 chanref:quit $victimhand
326 }
640024b7
MM
327 MOTD {
328 set targetsid [lindex $input 1]
329 }
331ad8b6
MM
330 NICK {
331 set oldnick [ts6:uid2nick $prefix]
332 set newnick [lindex $input 1]
333 ts6:changed-nick $oldnick $newnick
334 dccputchan 0 "$oldnick is now known as $newnick"
335 }
336 PASS {
640024b7
MM
337 global peersid
338 set peersid [lindex $input 4]
331ad8b6
MM
339 }
340 PING {
341 putdcc $idx "PONG :[lindex $input 1]"
342 }
343 PRIVMSG {
344 set nick [ts6:uid2nick $prefix]
345 set chan [lindex $input 1]
640024b7 346 set msg [lindex $input 2]
331ad8b6 347 if {$chan == "#partyline"} {
331ad8b6
MM
348 dccputchan 0 "<$nick$chan> $msg"
349 }
350 }
640024b7
MM
351 SERVER {
352 global peersid
353 set name [lindex $input 1]
354 set hops [lindex $input 2]
355 set desc [lindex $input 3]
356
357 if {$prefix == ""} {
358 putlog "Server: $name{$peersid} via self{$mysid}"
359 set sid2serv($peersid) [list $name $mysid $desc]
360 set serv2sid($name) $peersid
361 } else {
362 putlog "Server: $name{-} via $prefix{-}"
363 }
364 }
365 SID {
366 set name [lindex $input 1]
367 set hops [lindex $input 2]
368 set sid [lindex $input 3]
369 set desc [lindex $input 4]
370
371 putlog "Server: $name{$sid} via [ts6:sid2serv $prefix]{$prefix}"
372 set sid2serv($sid) [list $name $prefix $desc]
373 set serv2sid($name) $sid
374 }
331ad8b6
MM
375 SVINFO {
376 putdcc $idx "SVINFO 6 6 0 :[unixtime]"
377 }
378 TRACE {
640024b7 379 global myserv
331ad8b6
MM
380 global version
381 set traceeuid [lindex $input 1]
382 set myversion "eggdrop-[lindex $version 0]"
640024b7 383 ts6:sput "200 $prefix Link $myversion $traceeuid $myserv"
331ad8b6 384 if {[ts6:myuid $traceeuid]} {
640024b7
MM
385 if {[string length $traceeuid] == 3} {
386 set tracee [ts6:sid2serv $traceeuid]
387 } else {
388 set tracee [ts6:uid2nick $traceeuid]
389 ts6:sput "204 $prefix User users $tracee\[?@?\] (?) ? ?"
390 }
331ad8b6
MM
391 ts6:sput "262 $prefix $traceeuid :End of TRACE"
392 }
393 }
394 UID {
2d9c1b72 395 set nick [nicktolower [lindex $input 1]]
640024b7 396 set uid [lindex $input 8]
3db4fdad 397
331ad8b6 398 set nick2uid($nick) $uid
640024b7 399
c3bec97d 400 uid:set $uid NICK [lindex $input 1]
3db4fdad
MM
401 uid:set $uid USERNAME [lindex $input 5]
402 uid:set $uid HOSTNAME [lindex $input 6]
403 uid:set $uid REALNAME [lindex $input 9]
640024b7
MM
404 }
405 WALLOPS {
406 set from [ts6:id2name $prefix]
407 set msg [lindex $input 1]
408 putlog "Wallops ($from): $msg"
331ad8b6
MM
409 }
410 WHOIS {
331ad8b6 411 global botnet-nick
640024b7
MM
412 global myserv
413 global ts6-mynick
2d9c1b72
MM
414 set arg [lindex $input 2]
415 set uid [ts6:nick2uid $arg]
416 if {$uid != ""} {
417 set nick [ts6:uid2nick $uid]
418 set hand [ts6:nick2hand $nick]
419 if {$hand != ""} {
420 ts6:sput "311 $prefix $nick $hand ${botnet-nick} * :$hand"
421 ts6:sput "312 $prefix $nick $myserv :${botnet-nick}"
422 ts6:sput "330 $prefix $nick $hand :logged in as"
423 } else {
3db4fdad
MM
424 ts6:sput "311 $prefix $nick [uid:get $uid USERNAME ?] [uid:get $uid HOSTNAME ?] * :[uid:get $uid REALNAME ?]"
425 set login [uid:get $uid LOGIN *]
426 if {$login != "*"} {
427 ts6:sput "330 $prefix $nick $login :logged in to services as"
428 }
429 set hand [nick2hand $nick]
430 if {$hand != ""} {
431 ts6:sput "330 $prefix $nick $hand@${botnet-nick} :recognized by bot as"
432 }
331ad8b6
MM
433 }
434 #ts6:sput "317 $prefix $nick 123 [unixtime] :idle, login"
435 #ts6:sput "671 $prefix $nick :uses SSL"
436 ts6:sput "320 $prefix $nick :has TS6 uid $uid"
437 } else {
2d9c1b72 438 ts6:sput "401 $prefix $arg :No such nick"
331ad8b6 439 }
2d9c1b72 440 ts6:sput "318 $prefix $arg :End of /WHOIS"
331ad8b6
MM
441 }
442 }
443}
444
445proc go {} { ts6:connect 127.0.0.1 194 }
446
447proc redo {} {
448 global ts6-idx
449 killdcc ${ts6-idx}
640024b7 450 source scripts/g_ts6/g_ts6.tcl
331ad8b6
MM
451 go
452}
453
454bind chon - * partyline:online
455bind chof - * partyline:offline
456bind chjn - * partyline:join
457bind chpt - * partyline:part
458bind chat - * partyline:msg
459bind act - * partyline:act
460bind nkch - * partyline:nick
461
462proc partyline:online {hand idx} {
463 set uid [ts6:introduce $hand]
640024b7 464 ts6:put ":$uid JOIN [unixtime] #nullroute +"
331ad8b6
MM
465}
466
467proc partyline:offline {hand idx} {
468 global ts6-introduced
469 set uid [ts6:introduce $hand]
470 ts6:put ":$uid QUIT :Left the partyline"
471 unset ts6-introduced($uid)
472}
473
474proc partyline:join {bot hand chan flag idx uh} {
475 global uptime
476 if {$chan == "0"} {
477 if {[chanref:join $hand]} {
478 set uid [ts6:introduce $hand]
479 ts6:put ":$uid JOIN [unixtime] #partyline +"
640024b7 480 ts6:cput "TMODE $uptime #partyline +v $uid"
331ad8b6
MM
481 }
482 }
483}
484
485proc partyline:part {bot hand idx chan} {
486 global members
487 if {$chan == "0"} {
488 if {[chanref:part $hand]} {
489 set uid [ts6:introduce $hand]
490 ts6:put ":$uid PART #partyline"
491 }
492 }
493}
494
495proc partyline:msg {hand chan msg} {
496 if {$chan == "0"} {
497 set uid [ts6:introduce $hand]
498 ts6:put ":$uid PRIVMSG #partyline :$msg"
499 }
500}
501
502proc partyline:act {hand chan msg} {
503 if {$chan == "0"} {
504 set uid [ts6:introduce $hand]
505 ts6:put ":$uid PRIVMSG #partyline :\001ACTION $msg\001"
506 }
507}
508
509proc partyline:nick {oldhand newhand} {
510 chanref:rename $oldhand $newhand
511
512 set oldnick [ts6:hand2nick $oldhand]
513 set newnick [ts6:hand2nick $newhand]
2d9c1b72 514 set uid [ts6:nick2uid $oldnick]
331ad8b6
MM
515
516 ts6:changed-nick $oldnick $newnick
517
518 ts6:put ":$uid NICK $newnick [unixtime]"
519}