1 proc defset
{varname val
} {
3 if {![info exists var
]} { set var
$val }
11 defset ownfullname
"testing bot"
12 defset ownmailaddr test-irc-bot
@example.com
14 defset musthaveping_ms
10000
16 defset out_interval
2100
17 defset out_lag_lag
5000
18 defset out_lag_very
25000
20 defset marktime_min
300
21 defset marktime_join_startdelay
5000
23 proc manyset
{list args
} {
24 foreach val
$list var
$args {
30 proc try_except_finally
{try except finally
} {
31 global errorInfo errorCode
32 set er
[catch { uplevel 1 $try } emsg
]
36 if {[catch { uplevel 1 $except } emsg3
]} {
37 append ei
"\nALSO ERROR HANDLING ERROR:\n$emsg3"
40 set er2
[catch { uplevel 1 $finally } emsg2
]
43 append ei
"\nALSO ERROR CLEANING UP:\n$emsg2"
45 return -code $er -errorinfo $ei -errorcode $ec $emsg
47 return -code $er2 -errorinfo $errorInfo -errorcode $errorCode $emsg2
55 global out_queue out_creditms out_creditat out_interval out_maxburst
56 global out_lag_lag out_lag_very
57 #set pr [lindex [info level 0] 0]
58 #puts $pr>[clock seconds]|$out_creditat|$out_creditms|[llength $out_queue]<
64 if {[llength $out_queue]*$out_interval > $out_lag_very} {
66 } elseif
{[llength $out_queue]*$out_interval > $out_lag_lag} {
76 set now
[clock seconds
]
77 incr out_creditms
[expr {($now - $out_creditat) * 1000}]
79 if {$out_creditms > $out_maxburst*$out_interval} {
80 set out_creditms
[expr {$out_maxburst*$out_interval}]
85 proc out_runqueue
{now
} {
89 while {[llength $out_queue] && $out_creditms >= $out_interval} {
90 #puts rq>$now|$out_creditat|$out_creditms|[llength $out_queue]<
91 manyset
[lindex $out_queue 0] orgwhen msg
92 set out_queue
[lrange $out_queue 1 end
]
93 if {[llength $out_queue]} {
94 append orgwhen
"+[expr {$now - $orgwhen}]"
95 append orgwhen
"([llength $out_queue])"
97 puts "$orgwhen -> $msg"
99 incr out_creditms
-$out_interval
101 if {[llength $out_queue]} {
102 after $out_interval out_nextmessage
106 proc out_nextmessage
{} {
108 set now
[clock seconds
]
109 incr out_creditms
$out_interval
110 set out_creditat
$now
114 proc sendout_priority
{priority command args
} {
115 global sock out_queue
116 if {[llength $args]} {
117 set la
[lindex $args end
]
118 set args
[lreplace $args end end
]
120 if {[regexp {[: ]} $i]} {
121 error "bad argument in output $i ($command $args)"
126 set args
[lreplace $args 0 -1 $command]
127 set string [join $args { }]
128 set now
[clock seconds
]
129 set newe
[list $now $string]
131 set out_queue
[concat [list $newe] $out_queue]
133 lappend out_queue
$newe
135 if {[llength $out_queue] == 1} {
140 proc sendout
{command args
} { eval sendout_priority
[list 0 $command] $args }
146 proc logerror
{data
} {
151 global saveei saveec errorInfo errorCode
153 set saveei
$errorInfo
154 set saveec
$errorCode
156 puts ">$saveec|$saveei<"
166 global sock nick calling_nick errorInfo errorCode line_org_endchar
168 if {[gets $sock line
] == -1} { fail
"EOF/error on input" }
169 set line_org_endchar
[string range
$line end end
]
170 regsub -all "\[^ -\176\240-\376\]" $line ? line
175 if {[regexp -nocase {^
:([^
]+) (.
*)} $line dummy prefix remain
]} {
177 if {[regexp {^
([^
!]+)!} $prefix dummy maybenick
]} {
178 set calling_nick
$maybenick
179 if {"[irctolower $maybenick]" == "[irctolower $nick]"} return
184 if {![string length
$line]} { return }
185 if {![regexp -nocase {^
([0-9a-z
]+) *(.
*)} $line dummy command line
]} {
186 log
"bad command: $org"
189 set command
[string toupper
$command]
191 while {[regexp {^
([^
:]+) *(.
*)} $line dummy thisword line
]} {
192 lappend params
$thisword
194 if {[regexp {^
:(.
*)} $line dummy thisword
]} {
195 lappend params
$thisword
196 } elseif
{[string length
$line]} {
197 log
"junk at end: $org"
200 if {"$command" == "PRIVMSG" && \
201 [privmsg_unlogged
$prefix [ischan
[lindex $params 0]] $params]} {
204 log
"[clock seconds] <- $org"
205 set procname msg_
$command
206 if {[catch { info body
$procname }]} { return }
208 eval [list $procname $prefix $command] $params
210 logerror
"error: $emsg ($prefix $command $params)"
215 proc sendprivmsg
{dest l
} {
216 foreach v
[split $l "\n"] {
217 sendout
[expr {[ischan
$dest] ?
"PRIVMSG" : "NOTICE"}] $dest $v
220 proc sendaction_priority
{priority dest what
} {
221 sendout_priority
$priority PRIVMSG
$dest "\001ACTION $what\001"
223 proc msendprivmsg
{dest ll
} { foreach l
$ll { sendprivmsg
$dest $l } }
224 proc msendprivmsg_delayed
{delay dest ll
} { after $delay [list msendprivmsg
$dest $ll] }
226 proc check_nick
{n
} {
227 if {[regexp -nocase {[^
][\\`_^
{|
}a-z0-9-
]} $n]} { error "bad char in nick" }
228 if {[regexp {^
[-0-9]} $n]} { error "bad nick start" }
232 return [regexp {^
[&#+!]} $dest]
235 proc irctolower
{v
} {
236 foreach {from to
} [list "\\\[" "{" \
240 regsub -all $from $v $to v
242 return [string tolower
$v]
245 proc prefix_none
{} {
247 if {[string length
$p]} { error "prefix specified" }
250 proc prefix_nick
{} {
254 if {![regexp {^
([^
!]+)!} $p dummy n
]} { error "not from nick" }
256 if {"[irctolower $n]" == "[irctolower $nick]"} {
257 error "from myself" {} {}
261 proc msg_PING
{p c s1
} {
262 global musthaveping_after
265 if {[info exists musthaveping_after
]} {
266 after cancel
$musthaveping_after
267 unset musthaveping_after
272 proc ensure_outqueue
{} {
274 if {[info exists out_queue
]} return
276 set out_creditat
[clock seconds
]
278 set out_lag_reported
0
279 set out_lag_reportwhen
$out_creditat
283 logerror
"failing: $msg"
287 proc ensure_connecting
{} {
288 global sock ownfullname host port nick ident socketargs
289 global musthaveping_ms musthaveping_after
293 if {[info exists sock
]} return
294 set sock
[eval socket $socketargs [list $host $port]]
295 fconfigure $sock -buffering line
296 fconfigure $sock -translation crlf
298 sendout USER
$ident 0 * $ownfullname
300 fileevent $sock readable onread
302 set musthaveping_after
[after $musthaveping_ms \
303 {fail
"no ping within timeout"}]