tclserv

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

commit 9e2b737750c78f8bb76a3cd9acc88af5e8c363d8
parent 8f08e635b2a5a5ebbd15ce876f8e1bdb1a5e9f79
Author: Ellenor Malik ellenor@umbrellix.net <j4jackj@gmx.com>
Date:   Tue, 26 Jun 2018 15:47:07 -0700

ah stuff is just stuffed

Diffstat:
Mcore/0000-conn.tcl | 30++++++++++++++++++++++--------
Mcore/2000-protocol-common.tcl | 34+++++++++++++++++++++-------------
Mcore/2003-ts6.tcl | 172++++++++++++++++++++++++++++++++++++++++++-------------------------------------
Mcore/4000-eggcom.tcl | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Mmain.tcl | 2++
Mmodules/debugserv.tcl | 17+++++++++--------
Rmodules/0000-limitedeggcompat.tcl -> modules/nope.egg.nope | 0
Mmodules/quoteserv.tcl | 18+++++++++---------
Amodules/weather.tcl | 300+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9 files changed, 513 insertions(+), 141 deletions(-)

diff --git a/core/0000-conn.tcl b/core/0000-conn.tcl @@ -1,5 +1,8 @@ package require tls +# just to have sanity here. don't want a {} dict or a bum array +set $::netname(-) - + proc connect {addr port script} { if {[string index $port 0] == "+"} { set port [string range $port 1 end] ; set comd ::tls::socket } {set comd socket} set sck [$comd $addr $port] @@ -8,13 +11,7 @@ proc connect {addr port script} { return $sck } -proc mknetwork {a} { - set headlines [lrange $a 0 end-1] - set block [lindex $a end] - if {[catch {set ::sock($servername)} result] == 0} { - puts stdout "probably rehashing (duplicate network block, [tnda get rehashing], $result)" - return - } +proc mknetwork {headlines block} { if {[llength $headlines]<2} { puts stdout "fuck it, block's invalid ($headlines)" return @@ -26,6 +23,12 @@ proc mknetwork {a} { set port [dict get $block port] set servername [lindex $headlines 1] set netname [lindex $headlines 0] + if {[catch {set ::sock($netname)} result] == 0} { + if {![eof $::sock($netname)]} { + puts stdout "probably rehashing (connected network block, [tnda get rehashing], $result)" + return + } + } if {[dict exists $block prefixes]} { # only required for ts6 set prefixes [split [dict get $block prefix] " "] @@ -48,4 +51,15 @@ proc mknetwork {a} { postblock network $headlines $block } -blockwcb network mknetwork +proc core.conn.mknetworks {args} { + set blocks [tnda get "openconf/[ndcenc network]/blocks"]] + for {set i 1} {$i < ($blocks + 1)} {incr i} { + after 1000 [list mknetwork [tnda get [format "openconf/%s/hdr%s" [ndcenc network] $i]] [tnda get [format "openconf/%s/n%s" [ndcenc network] $i]]] + } +} + +blocktnd network + +llbind - evnt - confloaded core.conn.mknetworks + +#blockwcb network mknetwork diff --git a/core/2000-protocol-common.tcl b/core/2000-protocol-common.tcl @@ -1,20 +1,28 @@ -proc bind {sock type client comd script} { +proc llbind {sock type client comd script} { set moretodo 1 while {0!=$moretodo} { - set bindnum [rand 1 100000000] - if {[tnda get "binds/$sock/$type/$client/$comd/$bindnum"]!=""} {} {set moretodo 0} + set llbindnum [rand 1 100000000] + if {[tnda get "llbinds/$::netname($sock)/$type/$client/[ndcenc $comd]/$llbindnum"]!=""} {} {set moretodo 0} } - tnda set "binds/$sock/$type/$client/$comd/$bindnum" $script - return $bindnum + tnda set "llbinds/$::netname($sock)/$type/$client/[ndcenc $comd]/$llbindnum" $script + return $llbindnum } -proc unbind {sock type client comd id} { - tnda set "binds/$sock/$type/$client/$comd/$id" "" +proc unllbind {sock type client comd id} { + tnda set "llbinds/$::netname($sock)/$type/$client/[ndcenc $comd]/$id" "" + tnda unset "llbinds/$::netname($sock)/$type/$client/[ndcenc $comd]/$id" } -proc callbind {sock type client comd args} { -# puts stdout "$sock $type $client $comd $args" - if {""!=[tnda get "binds/$sock/$type/$client/$comd"]} { - foreach {id script} [tnda get "binds/$sock/$type/$client/$comd"] { +proc unllbindall {sock type client comd} { + tnda set "llbinds/$::netname($sock)/$type/$client/[ndcenc $comd]" "" + tnda unset "llbinds/$::netname($sock)/$type/$client/[ndcenc $comd]" +} +proc firellbind {sock type client comd args} { +# puts stdout "$sock $type $client [ndcenc $comd] $args" + global globuctx globctx + set globctx $::netname($sck) + set globuctx $client + if {""!=[tnda get "llbinds/$::netname($sock)/$type/$client/[ndcenc $comd]"]} { + foreach {id script} [tnda get "llbinds/$::netname($sock)/$type/$client/[ndcenc $comd]"] { if {$script != ""} { set scr $script # lappend $scr $sock @@ -22,10 +30,10 @@ proc callbind {sock type client comd args} { lappend scr $a } if {[catch {eval $scr} erre] > 0} {puts stdout $erre - callbind $sock evnt - error $erre {*}$scr + firellbind $sock evnt - error $erre {*}$scr } } };return } - #if {""!=[tnda get "binds/$type/-/$comd"]} {foreach {id script} [tnda get "binds/$type/-/$comd"] {$script [lindex $args 0] [lrange $args 1 end]};return} + #if {""!=[tnda get "llbinds/$type/-/[ndcenc $comd]"]} {foreach {id script} [tnda get "llbinds/$type/-/[ndcenc $comd]"] {$script [lindex $args 0] [lrange $args 1 end]};return} } diff --git a/core/2003-ts6.tcl b/core/2003-ts6.tcl @@ -252,7 +252,12 @@ proc ::ts6::quitstorm {sck sid comment {doinit 1}} { proc ::ts6::irc-main {sck} { global sid sock socksid - if {[eof $sck]} {close $sck} + if {[eof $sck]} { + putl stdout "We're dead, folks." +# firellbind $sck evnt "-" "ts6.dead" $::netname($sck) $sck + firellbind $sck evnt "-" "dead" $::netname($sck) $sck + close $sck + } gets $sck line setctx $::netname($sck) #puts stdout $line @@ -281,8 +286,8 @@ proc ::ts6::irc-main {sck} { # if {[lindex $comd [expr {$one + 2}]] != 1} {return};#we don't support jupes tnda set "servers/$::netname($sck)/[ndaenc [tnda get "socksid/$::netname($sck)"]]/name" [lindex $comd [expr {$one + 1}]] tnda set "servers/$::netname($sck)/[ndaenc [tnda get "socksid/$::netname($sck)"]]/description" [lindex $comd [expr {$one + 3}]] - callbind $sck evnt "-" "ts6.alive" $::netname($sck) ;#obvious - callbind $sck evnt "-" "alive" $::netname($sck) ;#obvious + firellbind $sck evnt "-" "ts6.alive" $::netname($sck) ;#obvious + firellbind $sck evnt "-" "alive" $::netname($sck) ;#obvious } "SID" { @@ -300,8 +305,8 @@ proc ::ts6::irc-main {sck} { if {$failedserver == $sid} { #yes, it's us. putcmdlog "We're dead, folks." - callbind $sck evnt "-" "ts6.dead" $::netname($sck) - callbind $sck evnt "-" "dead" $::netname($sck) + firellbind $sck evnt "-" "ts6.dead" $::netname($sck) + firellbind $sck evnt "-" "dead" $::netname($sck) return } # Mark all servers with an uplink in failedservers as split @@ -312,8 +317,8 @@ proc ::ts6::irc-main {sck} { foreach {uidd _} [tnda get "nick/$::netname($sck)"] { if {[string range $uidd 0 2] != $srv} {continue};# not a dead user foreach {chan _} [tnda get "userchan/$::netname($sck)/$uidd"] { - callbind $sck part "-" "-" [ndadec $chan] $uidd $::netname($sck) -# callbind $sck cquit "-" "-" [ndadec $chan] $uidd $::netname($sck) + firellbind $sck part "-" "-" [ndadec $chan] $uidd $::netname($sck) +# firellbind $sck cquit "-" "-" [ndadec $chan] $uidd $::netname($sck) tnda set "userchan/$::netname($sck)/$uidd/$chan" 0 } @@ -328,7 +333,7 @@ proc ::ts6::irc-main {sck} { tnda unset "ipaddr/$::netname($sck)/$uidd" tnda set "metadata/$::netname($sck)/$uidd" [list] tnda unset "certfps/$::netname($sck)/$uidd" - callbind $sck quit "-" "-" $uidd $::netname($sck) + firellbind $sck quit "-" "-" $uidd $::netname($sck) } } } @@ -377,12 +382,12 @@ proc ::ts6::irc-main {sck} { "PRIVMSG" { if {[::ts6::validchan $sck [lindex $comd 2]]} { set client chan - callbind $sck pub "-" [string tolower [lindex [split $payload " "] 0]] [lindex $comd 2] [lindex $comd 0] [join [lrange [split $payload " "] 1 end] " "] - callbind $sck evnt "-" "chanmsg" [lindex $comd 0] [lindex $comd 2] $payload + firellbind $sck pub "-" [string tolower [lindex [split $payload " "] 0]] [lindex $comd 2] [lindex $comd 0] [join [lrange [split $payload " "] 1 end] " "] + firellbind $sck evnt "-" "chanmsg" [lindex $comd 0] [lindex $comd 2] $payload } { set client [tnda get "intclient/$::netname($sck)/[lindex $comd 2]"] - callbind $sck msg $client [string tolower [lindex [split $payload " "] 0]] [lindex $comd 0] [join [lrange [split $payload " "] 1 end] " "] - callbind $sck "evnt" "-" "privmsg" [lindex $comd 0] [lindex $comd 2] $payload + firellbind $sck msg $client [string tolower [lindex [split $payload " "] 0]] [lindex $comd 0] [join [lrange [split $payload " "] 1 end] " "] + firellbind $sck "evnt" "-" "privmsg" [lindex $comd 0] [lindex $comd 2] $payload } } @@ -390,13 +395,13 @@ proc ::ts6::irc-main {sck} { if {![tnda get "ts6/$::netname($sck)/connected"]} {return} if {[::ts6::validchan $sck [lindex $comd 2]]} { set client chan - callbind $sck pubnotc "-" [string tolower [lindex [split $payload " "] 0]] [lindex $comd 2] [lindex $comd 0] [join [lrange [split $payload " "] 1 end] " "] -# callbind $sck pubnotc-m "-" [string tolower [lindex [split $payload " "] 0]] [lindex $comd 2] [lindex $comd 0] [join [lrange [split $payload " "] 1 end] " "] - callbind $sck "evnt" "-" "channotc" [lindex $comd 0] [lindex $comd 2] $payload + firellbind $sck pubnotc "-" [string tolower [lindex [split $payload " "] 0]] [lindex $comd 2] [lindex $comd 0] [join [lrange [split $payload " "] 1 end] " "] +# firellbind $sck pubnotc-m "-" [string tolower [lindex [split $payload " "] 0]] [lindex $comd 2] [lindex $comd 0] [join [lrange [split $payload " "] 1 end] " "] + firellbind $sck "evnt" "-" "channotc" [lindex $comd 0] [lindex $comd 2] $payload } { set client [tnda get "intclient/$::netname($sck)/[lindex $comd 2]"] - callbind $sck notc $client [string tolower [lindex [split $payload " "] 0]] [lindex $comd 0] [join [lrange [split $payload " "] 1 end] " "] - callbind $sck "evnt" "-" "privnotc" [lindex $comd 0] [lindex $comd 2] $payload + firellbind $sck notc $client [string tolower [lindex [split $payload " "] 0]] [lindex $comd 0] [join [lrange [split $payload " "] 1 end] " "] + firellbind $sck "evnt" "-" "privnotc" [lindex $comd 0] [lindex $comd 2] $payload } } @@ -414,8 +419,8 @@ proc ::ts6::irc-main {sck} { "JOIN" { set chan [string map {/ [} [::base64::encode [string tolower [lindex $comd 3]]]] - if {""==[tnda get "channels/$::netname($sck)/$chan/ts"]} {callbind $sck create "-" "-" [lindex $comd 3] [lindex $comd 0] $::netname($sck)} - callbind $sck join "-" "-" [lindex $comd 3] [lindex $comd 0] $::netname($sck) + if {""==[tnda get "channels/$::netname($sck)/$chan/ts"]} {firellbind $sck create "-" "-" [lindex $comd 3] [lindex $comd 0] $::netname($sck)} + firellbind $sck join "-" "-" [lindex $comd 3] [lindex $comd 0] $::netname($sck) tnda set "channels/$::netname($sck)/$chan/ts" [lindex $comd 2] tnda set "userchan/$::netname($sck)/[lindex $comd 0]/$chan" 1 } @@ -427,7 +432,7 @@ proc ::ts6::irc-main {sck} { set channel [lindex $comd 3] set type [lindex $comd 4] foreach {mask} $adding { - callbind $sck mode - + $type [lindex $comd 0] [lindex $comd 3] $mask $::netname($sck) + firellbind $sck mode - + $type [lindex $comd 0] [lindex $comd 3] $mask $::netname($sck) } } @@ -440,9 +445,9 @@ proc ::ts6::irc-main {sck} { } elseif {$c == "-"} { set state 0 } elseif {[string match [format "*%s*" $c] [tnda get "ts6/$::netname($sck)/chmparm"]] || ($state&&[string match [format "*%s*" $c] [tnda get "ts6/$::netname($sck)/chmpartparm"]])} { - callbind $sck mode "-" [expr {$state ? "+" : "-"}] $c [lindex $comd 0] [lindex $comd 3] [lindex $comd [incr ctr]] $::netname($sck) + firellbind $sck mode "-" [expr {$state ? "+" : "-"}] $c [lindex $comd 0] [lindex $comd 3] [lindex $comd [incr ctr]] $::netname($sck) } else { - callbind $sck mode "-" [expr {$state ? "+" : "-"}] $c [lindex $comd 0] [lindex $comd 3] "" $::netname($sck) + firellbind $sck mode "-" [expr {$state ? "+" : "-"}] $c [lindex $comd 0] [lindex $comd 3] "" $::netname($sck) } } } @@ -476,11 +481,11 @@ proc ::ts6::irc-main {sck} { # if {"uo"==$state} {append uo $c} # } putcmdlog [format "JOIN %s by nicknumber %s (nick %s, modes %s)" [ndadec $chan] $nick [tnda get "nick/$::netname($sck)/$un"] $uo] - callbind $sck join "-" "-" [lindex $comd 3] $un $::netname($sck) + firellbind $sck join "-" "-" [lindex $comd 3] $un $::netname($sck) tnda set "userchan/$::netname($sck)/$un/$chan" 1 if {""!=$uo} {tnda set "channels/$::netname($sck)/$chan/modes/$un" $uo foreach {c} [split $uo {}] { - callbind $sck mode "-" + $c $un [lindex $comd 3] $un $::netname($sck) + firellbind $sck mode "-" + $c $un [lindex $comd 3] $un $::netname($sck) } } } @@ -488,13 +493,13 @@ proc ::ts6::irc-main {sck} { } "PART" { - callbind $sck part "-" "-" [lindex $comd 2] [lindex $comd 0] $::netname($sck) + firellbind $sck part "-" "-" [lindex $comd 2] [lindex $comd 0] $::netname($sck) set chan [string map {/ [} [::base64::encode [string tolower [lindex $comd 2]]]] tnda set "userchan/$::netname($sck)/[lindex $comd 0]/$chan" 0 } "KICK" { - callbind $sck part "-" "-" [lindex $comd 2] [lindex $comd 3] $::netname($sck) + firellbind $sck part "-" "-" [lindex $comd 2] [lindex $comd 3] $::netname($sck) } "NICK" { @@ -528,7 +533,7 @@ proc ::ts6::irc-main {sck} { tnda set "ts/$::netname($sck)/[lindex $comd $num]" [lindex $comd 4] tnda set "rname/$::netname($sck)/[lindex $comd $num]" $payload #putloglev j * [format "New user at %s %s %s!%s@%s (IP address %s, vhost %s) :%s" $::netname($sck) [lindex $comd $num] [lindex $comd 2] [lindex $comd 6] [tnda get "rhost/$::netname($sck)/[lindex $comd $num]"] [lindex $comd 8] [tnda get "vhost/$::netname($sck)/[lindex $comd $num]"] $payload] - callbind $sck conn "-" "-" [lindex $comd $num] + firellbind $sck conn "-" "-" [lindex $comd $num] } "KLINE" {putloglev k * [format "KLINE: %s" $line]} @@ -538,7 +543,7 @@ proc ::ts6::irc-main {sck} { switch -nocase -- [lindex $comd 3] { "SASL" { # we have to support sasl messages, so... - callbind $sck encap - "sasl" [lrange $comd 4 end] + firellbind $sck encap - "sasl" [lrange $comd 4 end] #don't bother } "KLINE" { @@ -547,23 +552,23 @@ proc ::ts6::irc-main {sck} { "SU" { if {$payload == ""} {set payload [lindex $comd 5]} tnda set "login/$::netname($sck)/[lindex $comd 4]" $payload - if {$payload == ""} {callbind $sck logout "-" "-" [lindex $comd 4]} {callbind $sck login "-" "-" [lindex $comd 4] $payload} + if {$payload == ""} {firellbind $sck logout "-" "-" [lindex $comd 4]} {firellbind $sck login "-" "-" [lindex $comd 4] $payload} } "CERTFP" { tnda set "certfps/$::netname($sck)/[lindex $comd 0]" $payload - callbind $sck encap "-" "certfp" [lindex $comd 0] $payload + firellbind $sck encap "-" "certfp" [lindex $comd 0] $payload } "METADATA" { switch -nocase -- [lindex $comd 4] { "ADD" { tnda set "metadata/$::netname($sck)/[lindex $comd 5]/[ndcenc [lindex $comd 6]]" $payload - callbind $sck encap "-" "metadata.[string tolower [lindex $comd 6]]" [lindex $comd 5] $payload - callbind $sck mark "-" [lindex $comd 6] [lindex $comd 5] $payload + firellbind $sck encap "-" "metadata.[string tolower [lindex $comd 6]]" [lindex $comd 5] $payload + firellbind $sck mark "-" [lindex $comd 6] [lindex $comd 5] $payload } "DELETE" { tnda unset "metadata/$::netname($sck)/[lindex $comd 5]/[ndcenc $payload]" - callbind $sck encap "-" "metadata.[string tolower $payload]" [lindex $comd 5] "" - callbind $sck mark "-" $payload [lindex $comd 5] "" + firellbind $sck encap "-" "metadata.[string tolower $payload]" [lindex $comd 5] "" + firellbind $sck mark "-" $payload [lindex $comd 5] "" # WARNING!!!! Pick ONE. The official scripts use MARK; you should too. } } @@ -572,7 +577,7 @@ proc ::ts6::irc-main {sck} { } "TOPIC" { - callbind $sck topic "-" "-" [lindex $comd 2] [join $payload " "] + firellbind $sck topic "-" "-" [lindex $comd 2] [join $payload " "] } "QUIT" { if {![string is digit [string index [lindex $comd 0] 0]]} { @@ -582,7 +587,7 @@ proc ::ts6::irc-main {sck} { putcmdlog [format "Uh-oh, netsplit! %s -> %s has split" $on [::ts6::nick2uid $::netname($sck) $on]] } foreach {chan _} [tnda get "userchan/$::netname($sck)/[lindex $comd 0]"] { - callbind $sck part "-" "-" [ndadec $chan] [lindex $comd 0] $::netname($sck) + firellbind $sck part "-" "-" [ndadec $chan] [lindex $comd 0] $::netname($sck) tnda set "userchan/$::netname($sck)/[lindex $comd 0]/$chan" 0 } @@ -596,12 +601,12 @@ proc ::ts6::irc-main {sck} { tnda unset "ipaddr/$::netname($sck)/[lindex $comd 0]" tnda set "metadata/$::netname($sck)/[lindex $comd 0]" [list] tnda unset "certfps/$::netname($sck)/[lindex $comd 0]" - callbind $sck quit "-" "-" [lindex $comd 0] $::netname($sck) + firellbind $sck quit "-" "-" [lindex $comd 0] $::netname($sck) } "KILL" { foreach {chan _} [tnda get "userchan/$::netname($sck)/[lindex $comd 2]"] { - callbind $sck part "-" "-" [ndadec $chan] [lindex $comd 2] + firellbind $sck part "-" "-" [ndadec $chan] [lindex $comd 2] tnda set "userchan/$::netname($sck)/[lindex $comd 2]/$chan" 0 } tnda unset "login/$::netname($sck)/[lindex $comd 2]" @@ -614,7 +619,7 @@ proc ::ts6::irc-main {sck} { tnda unset "rname/$::netname($sck)/[lindex $comd 2]" tnda set "metadata/$::netname($sck)/[lindex $comd 2]" [list] tnda unset "certfps/$::netname($sck)/[lindex $comd 2]" - callbind $sck quit "-" "-" [lindex $comd 2] $::netname($sck) + firellbind $sck quit "-" "-" [lindex $comd 2] $::netname($sck) } "ERROR" { @@ -653,10 +658,12 @@ proc ::ts6::irc-main {sck} { #puts stdout [join [list $erreno $erreur] " "] } -proc ::ts6::login {sck {osid "42"} {password "link"} {servname "net"} {servername services.invalid}} { +# irrelevant parameters should simply be ignored. +proc ::ts6::login {sck {osid "42"} {password "link"} {servname "net"} {servername services.invalid} {cfg {}}} { set num [string repeat "0" [expr {3-[string length [::ts6::b64e $osid]]}]] append num [::ts6::b64e $osid] global netname sid sock nettype socksid snames + dictassign $cfg euid useeuid gecos gecos set snames($sck) $servername set netname($sck) $servname set nettype($servname) ts6 @@ -665,78 +672,81 @@ proc ::ts6::login {sck {osid "42"} {password "link"} {servname "net"} {servernam set sid($servname) $osid tnda set "ts6/$::netname($sck)/connected" 0 tnda set "ts6/$::netname($sck)/euid" 0 - if {![info exists ::ts6(halfops)]} {tnda set "pfx/halfop" v} {tnda set "pfx/halfop" $::ts6(halfops)} - if {![info exists ::ts6(ownermode)]} {tnda set "pfx/owner" o} {tnda set "pfx/owner" $::ts6(ownermode)} - if {![info exists ::ts6(protectmode)]} {tnda set "pfx/protect" o} {tnda set "pfx/protect" $::ts6(protectmode)} - if {![info exists ::ts6(euid)]} {set ::ts6(euid) 1} + #if {$halfops == ""} {tnda set "pfx/halfop" v} {tnda set "pfx/halfop" $halfops} + #if {![info exists ::ts6(ownermode)]} {tnda set "pfx/owner" o} {tnda set "pfx/owner" $ownermode)} + #if {![info exists ::ts6(protectmode)]} {tnda set "pfx/protect" o} {tnda set "pfx/protect" $protectmode} + if {$useeuid == ""} {tnda set "ts6/$::netname($sck)/euid" 1} {tnda set "ts6/$::netname($sck)/euid" $useeuid} + putl $sck "PASS $password TS 6 :$num" putl $sck "CAPAB :UNKLN BAN KLN RSFNC EUID ENCAP IE EX CLUSTER EOPMOD SVS SERVICES QS" putl $sck "SERVER $servername 1 :chary.tcl for Eggdrop and related bots" putl $sck "SVINFO 6 6 0 :[clock format [clock seconds] -format %s]" putl $sck ":$num VERSION" - bind $sck mode - + ::ts6::checkop - bind $sck mode - - ::ts6::checkdeop + llbind $sck mode - + ::ts6::checkop + llbind $sck mode - - ::ts6::checkdeop chan event $sck readable [list ::ts6::irc-main $sck] } #source services.conf -proc ::ts6::nick2uid {netname nick} { +proc ::ts6::nick2uid {sck nick} { foreach {u n} [tnda get "nick/$netname"] { if {[string tolower $n] == [string tolower $nick]} {return $u} } + return "" } -proc ::ts6::intclient2uid {netname nick} { +proc ::ts6::intclient2uid {sck nick} { foreach {u n} [tnda get "intclient/$netname"] { if {[string tolower $n] == [string tolower $nick]} {return $u} } + return "" } -proc ::ts6::uid2nick {netname u} { - return [tnda get "nick/$netname/$u"] +proc ::ts6::uid2nick {sck u} { + return [tnda get "nick/$::netname($sck)/$u"] } -proc ::ts6::uid2rhost {netname u} { - return [tnda get "rhost/$netname/$u"] +proc ::ts6::uid2rhost {sck u} { + return [tnda get "rhost/$::netname($sck)/$u"] } -proc ::ts6::uid2host {netname u} { - return [tnda get "vhost/$netname/$u"] +proc ::ts6::uid2host {sck u} { + return [tnda get "vhost/$::netname($sck)/$u"] } -proc ::ts6::uid2ident {netname u} { - return [tnda get "ident/$netname/$u"] +proc ::ts6::uid2ident {sck u} { + return [tnda get "ident/$::netname($sck)/$u"] } -proc ::ts6::nick2host {netname nick} { - return [tnda get "vhost/$netname/[nick2uid $netname $nick]"] +proc ::ts6::nick2host {sck nick} { + return [tnda get "vhost/$::netname($sck)/[nick2uid $netname $nick]"] } -proc ::ts6::nick2ident {netname nick} { - return [tnda get "ident/$netname/[nick2uid $netname $nick]"] +proc ::ts6::nick2ident {sck nick} { + return [tnda get "ident/$::netname($sck)/[nick2uid $netname $nick]"] } -proc ::ts6::nick2rhost {netname nick} { - return [tnda get "rhost/$netname/[nick2uid $netname $nick]"] +proc ::ts6::nick2rhost {sck nick} { + return [tnda get "rhost/$::netname($sck)/[nick2uid $netname $nick]"] } -proc ::ts6::nick2ipaddr {netname nick} { - return [tnda get "ipaddr/$netname/[nick2uid $netname $nick]"] +proc ::ts6::nick2ipaddr {sck nick} { + return [tnda get "ipaddr/$::netname($sck)/[nick2uid $netname $nick]"] } -proc ::ts6::getts {netname chan} { - return [tnda get "channels/$netname/[ndaenc $chan]/ts"] +proc ::ts6::getts {sck chan} { + return [tnda get "channels/$::netname($sck)/[ndaenc $chan]/ts"] } -proc ::ts6::getpfx {netname chan nick} { - return [tnda get "channels/$netname/[ndaenc $chan]/modes/[::ts6::nick2uid $netname $nick]"] +proc ::ts6::getpfx {sck chan nick} { + return [tnda get "channels/$::netname($sck)/[ndaenc $chan]/modes/[::ts6::nick2uid $netname $nick]"] } -proc ::ts6::getupfx {netname chan u} { - return [tnda get "channels/$netname/[ndaenc $chan]/modes/$u"] +proc ::ts6::getupfx {sck chan u} { + return [tnda get "channels/$::netname($sck)/[ndaenc $chan]/modes/$u"] } -proc ::ts6::getpfxchars {netname modes} { +proc ::ts6::getpfxchars {sck modes} { set o "" foreach {c} [split $modes {}] { - append o [nda get "ts6/$netname/prefix/$c"] + append o [nda get "ts6/$::netname($sck)/prefix/$c"] } return $o } -proc ::ts6::getmetadata {netname nick metadatum} { - return [tnda get "metadata/$netname/[::ts6::nick2uid $netname $nick]/[ndcenc $metadatum]"] +proc ::ts6::getmetadata {sck nick metadatum} { + return [tnda get "metadata/$::netname($sck)/[::ts6::nick2uid $netname $nick]/[ndcenc $metadatum]"] } -proc ::ts6::getcertfp {netname nick} { - return [tnda get "certfps/$netname/[::ts6::nick2uid $netname $nick]"] +proc ::ts6::getcertfp {sck nick} { + return [tnda get "certfps/$::netname($sck)/[::ts6::nick2uid $netname $nick]"] } proc ::ts6::checkop {mc s c p n} { @@ -757,17 +767,17 @@ putcmdlog "down $mc $f $t $p $n" tnda set "channels/$n/$chan/modes/$p" [string map [list $mc ""] [tnda get "channels/$n/$chan/modes/$p"]] } -proc ::ts6::formprefix {netname nick} { +proc ::ts6::formprefix {sck nick} { return [format ":%s " $nick] } -proc ::ts6::uid2intclient {netname u} { - return [tnda get "intclient/$netname/$u"] +proc ::ts6::uid2intclient {sck u} { + return [tnda get "intclient/$::netname($sck)/$u"] } -proc ::ts6::getfreeuid {net} { +proc ::ts6::getfreeuid {sck} { set work 1 set cns [list] -foreach {_ cnum} [tnda get "intclient/$net"] {lappend cns $cnum} +foreach {_ cnum} [tnda get "intclient/$::netname($sck)"] {lappend cns $cnum} while {0!=$work} {set num [expr {[rand 30000]+10000}];if {[lsearch -exact $cns $num]==-1} {set work 0}} return $num } diff --git a/core/4000-eggcom.tcl b/core/4000-eggcom.tcl @@ -1,8 +1,8 @@ #source chanserv.conf -#bind [curctx sock] mode "-" "+" bitchopcheck -#bind [curctx sock] mode "-" "-" protectopcheck -#bind [curctx sock] join "-" "-" autoopcheck +#llbind [curctx sock] mode "-" "+" bitchopcheck +#llbind [curctx sock] mode "-" "-" protectopcheck +#llbind [curctx sock] join "-" "-" autoopcheck proc protectopcheck {mc f t p} { if {"o"==$mc && ![channel get $t protectop]} {return} @@ -147,10 +147,10 @@ proc timers {} {set t {}; foreach a [after info] {lappend t "0 [lindex [after in proc killtimer id {return [after cancel $id]} proc killutimer id {return [after cancel $id]} -proc isbotnick {n} {return [expr {$n == $::botnick}]} - +proc isbotnick {n} {return [expr {$n == $::globuctx}]} set globctx "" +set globuctx "" proc setctx {ctx} { global globctx @@ -158,6 +158,18 @@ proc setctx {ctx} { set globctx $ctx } +proc setuctx {ctx} { + global globuctx + if {[% nick2uid $ctx] == ""} {return} ; # silently crap out + set globuctx [% uid2intclient [% nick2uid $ctx]] +} + +proc % {c args} { + set ul [list [curctx proto] $c [curctx sock]] + foreach {a} $args {lappend ul $a} + uplevel 1 $a +} + proc curctx {{type .net}} { if {$::globctx == ""} {return ""} switch -exact -- [format ".%s" [string tolower $type]] { @@ -167,6 +179,15 @@ proc curctx {{type .net}} { .net { return $::globctx } + .unum { + return $::globuctx + } + .uid { + return [% intclient2uid $::globuctx] + } + .user { + return [% uid2nick [% intclient2uid $::globuctx]] + } .proto { return $::nettype($::globctx) } @@ -175,7 +196,7 @@ proc curctx {{type .net}} { foreach {pname} [list putserv puthelp putquick putnow] { proc $pname {msg} { - puts [curctx sock] [[curctx proto] formprefix [curctx net] $msg] + puts [curctx sock] [[curctx proto] formprefix [curctx sock] $msg] } } @@ -186,7 +207,7 @@ proc msgmt {from msg} { [curctx proto] notice [curctx sock] 77 $from "$handle $attr $chan Matchattr result: [matchattr $handle $attr $chan]" } -#bind [curctx sock] msg 77 "matchattr" msgmt +#llbind [curctx sock] msg 77 "matchattr" msgmt proc matchattr {handle attr {chan "*"}} { set handle [string tolower $handle] @@ -194,14 +215,14 @@ proc matchattr {handle attr {chan "*"}} { set gattr [lindex [split $attr "&|"] 0] set cattr [lindex [split $attr "&|"] 1] set isattrg 0 - foreach {c} [split [nda get "eggcompat/attrs/global/$handle"] {}] { + foreach {c} [split [nda get "eggcompat/[curctx net]/attrs/global/$handle"] {}] { foreach {k} [split $gattr {}] { if {$c == $k} {set isattrg 1} } } set isattrc 0 if {"*"!=$chan} { - foreach {c} [split [nda get "eggcompat/attrs/[ndaenc $chan]/$handle"] {}] { + foreach {c} [split [nda get "eggcompat/[curctx net]/attrs/[ndaenc $chan]/$handle"] {}] { foreach {k} [split $cattr {}] { if {$c == $k} {set isattrc 1} } @@ -229,7 +250,7 @@ proc chattr {handle attr {chan "*"}} { append app $c } } - nda set "eggcompat/attrs/global/$handle" [join [concat [string map $del [nda get "eggcompat/attrs/global/$handle"]] $app] ""] + nda set "eggcompat/[curctx net]/attrs/global/$handle" [join [concat [string map $del [nda get "eggcompat/[curctx net]/attrs/global/$handle"]] $app] ""] } { set del [list] set app "" @@ -246,7 +267,7 @@ proc chattr {handle attr {chan "*"}} { } } puts stdout [ndaenc $chan] - nda set "eggcompat/attrs/[ndaenc $chan]/$handle" [join [concat [string map $del [nda get "eggcompat/attrs/[ndaenc $chan]/$handle"]] $app] ""] + nda set "eggcompat/[curctx net]/attrs/[ndaenc $chan]/$handle" [join [concat [string map $del [nda get "eggcompat/[curctx net]/attrs/[ndaenc $chan]/$handle"]] $app] ""] } } @@ -259,7 +280,7 @@ proc channels {} { namespace eval channel { proc ::channel::get {chan flag} { - if {[::set enda [nda get "eggcompat/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flag]]"]]!=""} {return $enda} {return 0} + if {[::set enda [nda get "eggcompat/[curctx net]/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flag]]"]]!=""} {return $enda} {return 0} } proc ::channel::set {chan flags} { if {[llength $flags] != 1} { @@ -267,13 +288,13 @@ namespace eval channel { ::set bit [string index $flag 0] if {$bit=="+"} {::set bitt 1} {::set bitt 0} ::set flag [string range $flag 1 end] - nda set "eggcompat/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flag]]" $bitt + nda set "eggcompat/[curctx net]/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flag]]" $bitt } } { ::set bit [string index $flags 0] if {$bit=="+"} {::set bitt 1} {::set bitt 0} ::set flag [string range $flags 1 end] - nda set "eggcompat/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flags]]" $bitt + nda set "eggcompat/[curctx net]/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flags]]" $bitt } } namespace export * @@ -284,9 +305,9 @@ proc validuser {n} { if {""==[nda get "usernames/$n"]} {return 0} {return 1} } -#bind [curctx sock] msg 77 "chanset" msgchanset -#bind [curctx sock] msg 77 "chattr" msgchattr -#bind [curctx sock] msg 77 "setxtra" msgxtra +#llbind [curctx sock] msg 77 "chanset" msgchanset +#llbind [curctx sock] msg 77 "chattr" msgchattr +#llbind [curctx sock] msg 77 "setxtra" msgxtra #set botnick $cs(nick) #chattr $cs(admin) +mnolv @@ -324,9 +345,9 @@ proc msgchattr {from msg} { } } if {""==$chan} {chattr $hand $attrs} {chattr $hand $attrs $chan} - [curctx proto] notice [curctx sock] 77 $from "Global flags for $hand are now [nda get "eggcompat/attrs/global/[string tolower $handle]"]" + [curctx proto] notice [curctx sock] 77 $from "Global flags for $hand are now [nda get "eggcompat/[curctx net]/attrs/global/[string tolower $handle]"]" if {""==[nda get "regchan/$ndacname/levels/[string tolower $hand]"]} {nda set "regchan/$ndacname/levels/[string tolower $hand]" 1} - if {$ch != ""} {[curctx proto] notice [curctx sock] 77 $from "Flags on $chan for $hand are now [nda get "eggcompat/attrs/$ndacname/[string tolower $handle]"]"} + if {$ch != ""} {[curctx proto] notice [curctx sock] 77 $from "Flags on $chan for $hand are now [nda get "eggcompat/[curctx net]/attrs/$ndacname/[string tolower $handle]"]"} } proc nick2hand {nick} { @@ -363,7 +384,6 @@ proc channame2dname {channame} {return $channame} proc islinked {bot} {return 0} - proc operHasPrivilege {n i p} { # this bit requires irca. set metadatum [tnda get "metadata/$n/$i/[ndcenc PRIVS]"] @@ -399,9 +419,26 @@ proc ishalf {chan id} { } proc ismode {chan id mode} { - if {[string first $mode [[curctx proto] getupfx [curctx net] $chan $id]] != -1} {return 1} {return 0} + if {[string first $mode [[curctx proto] getupfx [curctx sock] $chan $id]] != -1} {return 1} {return 0} } proc ismodebutnot {chan id mode} { - if {[string length [[curctx proto] getupfx [curctx net] $chan $id]] > 0 && [string first $mode [[curctx proto] getupfx [curctx net] $chan $id]] == -1} {return 1} {return 0} + if {[string length [[curctx proto] getupfx [curctx sock] $chan $id]] > 0 && [string first $mode [[curctx proto] getupfx [curctx sock] $chan $id]] == -1} {return 1} {return 0} +} + +# rules are odd. you should store the bind return in a variable to unbind it. +# flags aren't part of the bind define. +proc bind {type flag text script} { + set ctxsock [curctx sock] + set ctxuser [curctx unum] + return [llbind $ctxsock $type $ctxuser [list matchthenrun $ctxsock $ctxuser $flag $script]] +} + +proc matchthenrun {sock user flags script args} { + #setctx $sock + foreach {a} $args { + lappend script $a + } +# matchattr [uid2hand $user] $flags + eval $script } diff --git a/main.tcl b/main.tcl @@ -65,8 +65,10 @@ proc save.db {name var no oper} { # ensure DB save is atomic, so if tclserv is killed during or under 12.5 seconds after save catch [list file rename $name [format "%s.bk%s" $name $now]] set there [open $name [list WRONLY CREAT TRUNC BINARY]] + chan configure $there -blocking 0 -buffering full -buffersize 8192 # should not block for long puts -nonewline $there $db + flush $there close $there after 12500 [list catch [list file delete -- [format "%s.bk%s" $name $now]]] return diff --git a/modules/debugserv.tcl b/modules/debugserv.tcl @@ -1,6 +1,6 @@ blocktnd debugserv -bind - evnt - confloaded debugserv.connect +llbind - evnt - confloaded debugserv.connect proc debugserv.connect {arg} { puts stdout [format "there are %s debugserv blocks" [set blocks [tnda get "openconf/[ndcenc debugserv]/blocks"]]] @@ -39,10 +39,11 @@ proc debugserv.oneintro {headline block} { tnda set "debugserv/$net/logchan" $logchan #tnda set "debugserv/$net/nspass" $nspass setctx $net - $::nettype($net) sendUid $nsock $nick $ident $host $host [set ourid [$::nettype($net) getfreeuid $net]] [expr {($realname == "") ? "* Debug Service *" : $realname}] $modes + if {[% intclient2uid [tnda get "debugserv/$net/ourid"]] == ""} {$::nettype($net) sendUid $nsock $nick $ident $host $host [set ourid [$::nettype($net) getfreeuid $net]] [expr {($realname == "") ? "* Debug Service *" : $realname}] $modes} + setuctx $nick tnda set "debugserv/$net/ourid" $ourid - bind $nsock pub - ".metadata" [list debugserv.pmetadata $net] -# bind $nsock pub - ".rehash" [list debugserv.crehash $net] + llbind $nsock pub - ".metadata" [list debugserv.pmetadata $net] + llbind $nsock pub - ".rehash" [list debugserv.crehash $net] if {[string length $nspass] != 0 && [string length $nickserv] != 0} { # only works if nettype is ts6! if {[string first [debugserv.find6sid $net $nsserv] [$::nettype($net) nick2uid $net $nickserv]] == 0} { @@ -53,10 +54,10 @@ proc debugserv.oneintro {headline block} { } after 650 $::nettype($net) putjoin $nsock $ourid $logchan after 700 [list $::nettype($net) putmode $nsock $ourid $logchan "+ao" [format "%s %s" [$::nettype($net) intclient2uid $net $ourid] [$::nettype($net) intclient2uid $net $ourid]]] - bind $nsock msg [tnda get "debugserv/$net/ourid"] "metadata" [list debugserv.metadata $net] -# bind $nsock msg [tnda get "debugserv/$net/ourid"] "rehash" [list debugserv.rehash $net] -# bind $nsock pub - "gettext" [list debugserv.gettext $net] - puts stdout "bind $nsock msg [tnda get "debugserv/$net/ourid"] metadata [list debugserv.metdata $net]" + llbind $nsock msg [tnda get "debugserv/$net/ourid"] "metadata" [list debugserv.metadata $net] + llbind $nsock msg [tnda get "debugserv/$net/ourid"] "rehash" [list debugserv.rehash $net] +# llbind $nsock pub - "gettext" [list debugserv.gettext $net] + puts stdout "llbind $nsock msg [tnda get "debugserv/$net/ourid"] metadata [list debugserv.metdata $net]" puts stdout [format "Connected for %s: %s %s %s" $net $nick $ident $host] } diff --git a/modules/0000-limitedeggcompat.tcl b/modules/nope.egg.nope diff --git a/modules/quoteserv.tcl b/modules/quoteserv.tcl @@ -3,7 +3,7 @@ blocktnd qshelp source quoteserv.help -bind - evnt - confloaded quoteserv.connect +llbind - evnt - confloaded quoteserv.connect proc quoteserv.connect {arg} { puts stdout [format "there are %s quoteserv blocks" [set blocks [tnda get "openconf/[ndcenc quoteserv]/blocks"]]] @@ -41,8 +41,8 @@ proc quoteserv.oneintro {headline block} { setctx $net $::nettype($net) sendUid $nsock $nick $ident $host $host [set ourid [$::nettype($net) getfreeuid $net]] [expr {($realname == "") ? "* Debug Service *" : $realname}] $modes tnda set "quoteserv/[curctx net]/ourid" $ourid -# bind $nsock pub - ".metadata" [list quoteserv.pmetadata $net] -# bind $nsock pub - ".rehash" [list quoteserv.crehash $net] +# llbind $nsock pub - ".metadata" [list quoteserv.pmetadata $net] +# llbind $nsock pub - ".rehash" [list quoteserv.crehash $net] if {[string length $nspass] != 0 && [string length $nickserv] != 0} { # only works if nettype is ts6! if {[string first [quoteserv.find6sid $net $nsserv] [$::nettype($net) nick2uid $net $nickserv]] == 0} { @@ -53,13 +53,13 @@ proc quoteserv.oneintro {headline block} { } after 650 $::nettype($net) putjoin $nsock $ourid $logchan after 700 [list $::nettype($net) putmode $nsock $ourid $logchan "+ao" [format "%s %s" [$::nettype($net) intclient2uid $net $ourid] [$::nettype($net) intclient2uid $net $ourid]]] -# bind $nsock msg [tnda get "quoteserv/[curctx net]/ourid"] "metadata" [list quoteserv.metadata $net] -# bind $nsock msg [tnda get "quoteserv/[curctx net]/ourid"] "rehash" [list quoteserv.rehash $net] -# bind $nsock pub - "gettext" [list quoteserv.gettext $net] -# puts stdout "bind $nsock msg [tnda get "quoteserv/[curctx net]/ourid"] metadata [list quoteserv.metdata $net]" +# llbind $nsock msg [tnda get "quoteserv/[curctx net]/ourid"] "metadata" [list quoteserv.metadata $net] +# llbind $nsock msg [tnda get "quoteserv/[curctx net]/ourid"] "rehash" [list quoteserv.rehash $net] +# llbind $nsock pub - "gettext" [list quoteserv.gettext $net] +# puts stdout "llbind $nsock msg [tnda get "quoteserv/[curctx net]/ourid"] metadata [list quoteserv.metdata $net]" puts stdout [format "Connected for %s: %s %s %s" $net $nick $ident $host] - bind $nsock pub - "!quote" [list quoteservdo $net] - bind $nsock evnt - privmsg [list qs.pmdo $net] + llbind $nsock pub - "!quote" [list quoteservdo $net] + llbind $nsock evnt - privmsg [list qs.pmdo $net] puts stdout $::nd foreach {chan is} [nda get "quoteserv/[curctx net]/regchan"] { puts stdout "to join $chan on [curctx]" diff --git a/modules/weather.tcl b/modules/weather.tcl @@ -0,0 +1,300 @@ +blocktnd weatherserv +blocktnd wshelp + +source weatherserv.help + +llbind - evnt - confloaded weatherserv.connect + +proc weatherserv.connect {arg} { + puts stdout [format "there are %s weatherserv blocks" [set blocks [tnda get "openconf/[ndcenc weatherserv]/blocks"]]] + for {set i 1} {$i < ($blocks + 1)} {incr i} { + after 1000 [list weatherserv.oneintro [tnda get [format "openconf/%s/hdr%s" [ndcenc weatherserv] $i]] [tnda get [format "openconf/%s/n%s" [ndcenc weatherserv] $i]]] + } +} + +proc weatherserv.find6sid {n s {hunting 0}} { + # we're trying to get the sid of the server named $s + # if hunting, we're looking for the first splat match + set servs [tnda get "servers/$n"] + foreach {.k dv} $servs { + set k [string toupper [ndadec ${.k}]] + # name description uplink sid - we only need two + dictassign $dv name sname + if {$hunting} { + if {[string match [string tolower $s] [string tolower $sname]] == 1} {return $k} + } { + if {[string tolower $s] == [string tolower $sname]} {return $k} + } + } + return "" +} + +proc weatherserv.oneintro {headline block} { + set net [lindex $headline 0] + set nsock $::sock($net) + setctx $net + dictassign $block logchan logchan nick nick ident ident host host modes modes realname realname operflags rehashprivs idcommand nspass \ + nickserv nickserv nsserv nsserv + tnda set "weather/[curctx net]/operflags" $rehashprivs + tnda set "weather/[curctx net]/logchan" $logchan + #tnda set "weather/[curctx net]/nspass" $nspass + setctx $net + $::nettype($net) sendUid $nsock $nick $ident $host $host [set ourid [$::nettype($net) getfreeuid $net]] [expr {($realname == "") ? "* Debug Service *" : $realname}] $modes + tnda set "weather/[curctx net]/ourid" $ourid +# llbind $nsock pub - ".metadata" [list weatherserv.pmetadata $net] +# llbind $nsock pub - ".rehash" [list weatherserv.crehash $net] + if {[string length $nspass] != 0 && [string length $nickserv] != 0} { + # only works if nettype is ts6! + if {[string first [weatherserv.find6sid $net $nsserv] [$::nettype($net) nick2uid $net $nickserv]] == 0} { + $::nettype($net) privmsg $nsock $ourid $nickserv $nspass + } { + $::nettype($net) privmsg $nsock $ourid $logchan [gettext weatherserv.impostornickserv $nickserv [$::nettype($net) nick2uid $n $nickserv] $nsserv [weatherserv.find6sid $net $nsserv]] + } + } + after 650 [list $::nettype($net) putjoin $nsock $ourid $logchan] + after 950 [list $::nettype($net) putmode $nsock $ourid $logchan "+ao" [format "%s %s" [$::nettype($net) intclient2uid $net $ourid] [$::nettype($net) intclient2uid $net $ourid]]] +# llbind $nsock msg [tnda get "weather/[curctx net]/ourid"] "metadata" [list weatherserv.metadata $net] +# llbind $nsock msg [tnda get "weather/[curctx net]/ourid"] "rehash" [list weatherserv.rehash $net] +# llbind $nsock pub - "gettext" [list weatherserv.gettext $net] +# puts stdout "llbind $nsock msg [tnda get "weather/[curctx net]/ourid"] metadata [list weatherserv.metdata $net]" + puts stdout [format "Connected for %s: %s %s %s" $net $nick $ident $host] + llbind $nsock pub - "!quote" [list weatherservdo $net] + llbind $nsock evnt - privmsg [list ws.pmdo $net] + puts stdout $::nd + foreach {chan is} [nda get "weather/[curctx net]/regchan"] { + puts stdout "to join $chan on [curctx]" + if {1!=$is} {continue} + weatherjoin [ndadec $chan] 0 +# [curctx proto] putjoin [curctx sock] [tnda get "weather/[curctx net]/ourid"] [::base64::decode [string map {[ /} $chan]] [nda get "regchan/$chan/ts"] +# tnda set "channels/$chan/ts" [nda get "regchan/$chan/$::netname([curctx sock])/ts"] + } +} + +#$::maintype sendUid [curctx sock] "W" "weather" "services." "services." 57 "Weather Services" +llbind [curctx sock] request "w" "-" weatherjoin +llbind [curctx sock] request "weather" "-" weatherjoin + +proc weatherjoin {chan {setting 1}} { + set ndacname [string map {/ [} [::base64::encode [string tolower $chan]]] + puts stdout "to join $chan on [curctx]" + [curctx proto] putjoin [curctx sock] [tnda get "weather/[curctx net]/ourid"] $chan + [curctx proto] putmode [curctx sock] [tnda get "weather/[curctx net]/ourid"] $chan "+ao" \ + [format "%s %s" [[curctx proto] intclient2uid [curctx net] [tnda get "weather/[curctx net]/ourid"]]\ + [[curctx proto] intclient2uid [curctx net] [tnda get "weather/[curctx net]/ourid"]]] + if {$setting} {nda set "weather/[curctx net]/regchan/$ndacname" 1} +} + +proc weatherpart {chan {who "the script"} {msg isunused}} { + set ndacname [string map {/ [} [::base64::encode [string tolower $chan]]] + [curctx proto] putpart [curctx sock] [tnda get "weather/[curctx net]/ourid"] $chan [gettext weather.left $who] + nda set "weather/[curctx net]/regchan/$ndacname" 0 + nda unset "weather/[curctx net]/regchan/$ndacname" +} + +proc weatherenabled {chan} { + set ndacname [string map {/ [} [::base64::encode [string tolower $chan]]] + if {[nda get "weather/[curctx net]/regchan/$ndacname"] == 1} {return 1} {return 0} +} + +############################################################################################## +## ## wunderground.tcl for eggdrop by Ford_Lawnmower irc.geekshed.net #Script-Help ## ## +############################################################################################## +## To use this script you must set channel flag +weather (ie .chanset #chan +weather) ## +############################################################################################## +############################################################################################## +## ## Start Setup. ## ## +############################################################################################## +namespace eval wunderground { +## Edit logo to change the logo displayed at the start of the line ## ## + variable logo "\017\00304\002W\00304u\00307n\00308d\00311e\00312r\00304g\00307r\00308o\00311u\00312n\00304d\017" +## Edit textf to change the color/state of the text shown ## ## + variable textf "\017" +## Edit tagf to change the color/state of the Tags: ## ## + variable tagf "\017\002" +## Edit weatherline, line1, line2, line3, line4 to change what is displayed ## ## +## weatherline is for the !weather trigger and line1-4 are for !forecast ## ## +## Valid items are: location weatherstation conditions tempf tempc tempfc feelsf ## ## +## feelsc feelsfc windgust windspeed winddirection sunset sunrise moon ## ## +## day1 day2 day3 day4 day5 day6 day7 day8 day9 day10 ## ## +## Do not remove any variables here! Just change them to "" to suppress display ## ## + variable line1 "location weatherstation conditions tempfc feelsfc windspeed winddirection windgust sunset sunrise moon" + variable line3 "" + variable line2 "day1 day2 day3 day4 day5 day6 day7 day8 day9 day10" + variable line4 "" + variable weatherline "location weatherstation conditions tempfc feelsfc windspeed winddirection windgust sunset sunrise moon day1 day2 day3" +## Edit cmdchar to change the !trigger used to for this script ## ## + variable cmdchar "!" +############################################################################################## +## ## End Setup. ## ## +############################################################################################## + llbind [curctx sock] pub "-" [string trimleft $wunderground::cmdchar]weather wunderground::tclservwe + llbind [curctx sock] pub "-" [string trimleft $wunderground::cmdchar]wz wunderground::tclservwe + llbind [curctx sock] pub "-" [string trimleft $wunderground::cmdchar]forecast wunderground::tclservfc +} + +proc wunderground::tclservwe {n cname i msg} { + if {[weatherenabled $cname] == 0} {return} + set nick [tnda get "nick/$::netname([curctx sock])/$i"] + set host "[tnda get "ident/$i"]@[tnda get "vhost/$::netname([curctx sock])/$i"]" + set comd "weather" + set hand "" + set text $msg + wunderground::main $comd $nick $host $hand $cname $text +} + +proc wunderground::tclservfc {n cname i msg} { + if {[weatherenabled $cname] == 0} {return} + set nick [tnda get "nick/$::netname([curctx sock])/$i"] + set host "[tnda get "ident/$i"]@[tnda get "vhost/$::netname([curctx sock])/$i"]" + set comd "forecast" + set hand "" + set text $msg + wunderground::main $comd $nick $host $hand $cname $text +} + +proc wunderground::main {command nick host hand chan text} { + set search [strip $text] + set div ""; set moon ""; set sunset ""; set sunrise ""; set windspeed ""; set div "" + set winddirection ""; set location ""; set weatherstation ""; set temperature ""; set tempfc "" + set conditions ""; set feelslike ""; set feelsf ""; set feelsc ""; set city ""; set day "" + set details ""; set forc ""; set count 1; set tempf ""; set state_name ""; set tempc "" + set day1 ""; set day2 ""; set day3 ""; set day4 ""; set day5 ""; set state_name "" + set day6 ""; set day7 ""; set day8 ""; set day9 ""; set day10 ""; set windgust ""; set feelsfc "" + set wundergroundurl "/cgi-bin/findweather/hdfForecast?query=[urlencode $search]" + set wundergroundsite "www.wunderground.com" + if {"wz" == $command} {set command weather} + if {[catch {set wundergroundsock [socket -async $wundergroundsite 80]} sockerr]} { + return 0 + } else { + puts $wundergroundsock "GET $wundergroundurl HTTP/1.0" + puts $wundergroundsock "Host: $wundergroundsite" + puts $wundergroundsock "User-Agent: Opera 9.6" + puts $wundergroundsock "" + flush $wundergroundsock + while {![eof $wundergroundsock]} { + set wundergroundvar " [gets $wundergroundsock] " + regexp -nocase {"(current)_observation":} $wundergroundvar match div + regexp -nocase {"(forecast)":} $wundergroundvar match div + regexp -nocase {"(astronomy)":} $wundergroundvar match div + if {[regexp -nocase {"city":"([^"]*)} $wundergroundvar match city]} { + if {$city == "null"} { + set city "" + } + } elseif {[regexp -nocase {"state_name":"([^"]*)} $wundergroundvar match state_name]} { + if {$state_name == "null"} { + set state_name "" + } + set location "${wunderground::tagf}Location: ${wunderground::textf}${city}, $state_name" + } elseif {[regexp -nocase {"name":"([^"]*)} $wundergroundvar match weatherstation]} { + set weatherstation "${wunderground::tagf}Station: ${wunderground::textf}${weatherstation}" + } elseif {$forc == "" && [regexp -nocase {class="wx-unit">&nbsp;&deg;(.*?)<\/span>} $wundergroundvar match forc]} { + } elseif {[regexp -nocase {"condition":"([^"]*)} $wundergroundvar match conditions]} { + set conditions "${wunderground::tagf}Conditions: ${wunderground::textf}${conditions}" + } elseif {$div == "current" && [regexp -nocase {"temperature":\s([^\,]*)} $wundergroundvar match temperature]} { + set tempf "${wunderground::tagf}Temperature: ${wunderground::textf}[forc ${temperature} $forc F] deg F" + set tempc "${wunderground::tagf}Temperature: ${wunderground::textf}[forc ${temperature} $forc C] deg C" + set tempfc "${wunderground::tagf}Temperature: ${wunderground::textf}[forc ${temperature} $forc F] deg F/[forc ${temperature} $forc C] deg C" + } elseif {$div == "current" && [regexp -nocase {"feelslike":\s([^\,]*)} $wundergroundvar match feelslike]} { + set feelsf "${wunderground::tagf}Feels Like: ${wunderground::textf}[forc ${feelslike} $forc F] deg F" + set feelsc "${wunderground::tagf}Feels Like: ${wunderground::textf}[forc ${feelslike} $forc C] deg C" + set feelsfc "${wunderground::tagf}Feels Like: ${wunderground::textf}[forc ${feelslike} $forc F] deg F/[forc ${feelslike} $forc C] deg C" + } elseif {$div == "current" && [regexp -nocase {"wind_speed":\s?([^\,]*)} $wundergroundvar match windspeed]} { + set windspeed "${wunderground::tagf}Wind speed: ${wunderground::textf}${windspeed}" + } elseif {$div == "current" && [regexp -nocase {"wind_gust_speed":\s?([^\,]*)} $wundergroundvar match windgust]} { + set windgust "${wunderground::tagf}Wind gust: ${wunderground::textf}${windgust}" + } elseif {[regexp -nocase {"wind_dir":"([^"]*)} $wundergroundvar match winddirection]} { + set winddirection "${wunderground::tagf}Wind Direction: ${wunderground::textf}${winddirection}" + } elseif {[regexp -nocase {id="cc-sun-rise">(.*?)</span>\s?<span class="ampm">(.*?)</span>} $wundergroundvar match sunrise ampm]} { + set sunrise "${wunderground::tagf}Sunrise: ${wunderground::textf}${sunrise}${ampm}" + } elseif {[regexp -nocase {id="cc-sun-set">(.*?)</span> <span class="ampm">(.*?)</span>} $wundergroundvar match sunset ampm]} { + set sunset "${wunderground::tagf}Sunset: ${wunderground::textf}${sunset}${ampm}" + } elseif {[regexp -nocase {id="cc-moon-phase".*">(.+?)<\/span>} $wundergroundvar match moon]} { + set moon "${wunderground::tagf}Moon: ${wunderground::textf}${moon}" + } elseif {$div == "forecast" && $command == "weather"} { + msg $chan $wunderground::logo ${wunderground::textf} [subst [regsub -all -nocase {(\S+)} $wunderground::weatherline {$\1}]] + close $wundergroundsock + return 0 + } elseif {[regexp -nocase {<div\sclass="fctDayDate">(.+)\,} $wundergroundvar match day]} { + set day "${wunderground::tagf}${day}" + } elseif {[string match "forecast" $div]} { + if {[regexp -nocase {"weekday_short":\s?"([^"]*)} $wundergroundvar match day]} { + set day "${wunderground::tagf}${day}:->" + } elseif {[regexp -nocase {"high":\s([^\,]*)} $wundergroundvar match high]} { + set high "${wunderground::tagf}High:${wunderground::textf}[forc $high $forc F] deg F/[forc $high $forc C] deg C" + } elseif {[regexp -nocase {"low":\s([^\,]*)} $wundergroundvar match low]} { + set low "${wunderground::tagf}low:${wunderground::textf}[forc $low $forc F] deg F/[forc $low $forc C] deg C" + } elseif {[regexp -nocase {"condition":\s?"([^"]*)} $wundergroundvar match condition]} { + set condition "${wunderground::tagf}Cond:${wunderground::textf}${condition}" + } elseif {[regexp -nocase {"day":\s?\{} $wundergroundvar]} { + set day${count} "$day $high $low $condition" + incr count + } + } elseif {$div == "astronomy"} { + if {$wunderground::line1 != ""} { + msg $chan $wunderground::logo $wunderground::textf [subst [regsub -all -nocase {(\S+)} $wunderground::line1 {$\1}]] + } + if {$wunderground::line2 != ""} { + msg $chan $wunderground::logo $wunderground::textf [subst [regsub -all -nocase {(\S+)} $wunderground::line2 {$\1}]] + } + if {$wunderground::line3 != ""} { + msg $chan $wunderground::logo $wunderground::textf [subst [regsub -all -nocase {(\S+)} $wunderground::line3 {$\1}]] + } + if {$wunderground::line4 != ""} { + msg $chan $wunderground::logo $wunderground::textf [subst [regsub -all -nocase {(\S+)} $wunderground::line4 {$\1}]] + } + close $wundergroundsock + return 0 + } + } + } +} +proc wunderground::forc {value fc forc} { + if {[string equal -nocase $fc $forc]} { + return $value + } elseif {[string equal -nocase "f" $fc]} { + if {[expr {(($value - 32) * 5)} == 0]} { return 0 } + return [format "%.1f" [expr {(($value - 32) * 5) / 9}]] + } elseif {[string equal -nocase "c" $fc]} { + if {$value == 0} { return 32 } + return [format "%.1f" [expr {(($value * 9) / 5) + 32}]] + } +} +proc wunderground::striphtml {string} { + return [string map {&quot; \" &lt; < &rt; >} [regsub -all {(<[^<^>]*>)} $string ""]] +} +proc wunderground::urlencode {string} { + regsub -all {^\{|\}$} $string "" string + return [subst [regsub -nocase -all {([^a-z0-9\+])} $string {%[format %x [scan "\\&" %c]]}]] +} +proc wunderground::strip {text} { + regsub -all {\002|\031|\015|\037|\017|\003(\d{1,2})?(,\d{1,2})?} $text "" text + return $text +} +proc wunderground::msg {chan logo textf text} { + set text [textsplit $text 50] + set counter 0 + while {$counter <= [llength $text]} { + if {[lindex $text $counter] != ""} { + % privmsg [tnda get "weatherserv/[curctx net]/ourid"] $chan "${logo} ${textf}[string map {\\\" \"} [lindex $text $counter]]" + } + incr counter + } +} +proc wunderground::textsplit {text limit} { + set text [split $text " "] + set tokens [llength $text] + set start 0 + set return "" + while {[llength [lrange $text $start $tokens]] > $limit} { + incr tokens -1 + if {[llength [lrange $text $start $tokens]] <= $limit} { + lappend return [join [lrange $text $start $tokens]] + set start [expr $tokens + 1] + set tokens [llength $text] + } + } + lappend return [join [lrange $text $start $tokens]] + return $return +} +puts stdout "\002*Loaded* \00304\002W\00304u\00307n\00308d\00311e\00312r\00304g\00307r\00308o\00311u\00312n\00304d\017 \002by \ +Ford_Lawnmower irc.GeekShed.net #Script-Help"