From: ijackson Date: Tue, 15 Aug 2000 22:00:25 +0000 (+0000) Subject: Bot remembers "seen" and tells you about it later. X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=b13d57f068e5153daa2a2403b32a7bdea109f5ce;p=ircbot.git Bot remembers "seen" and tells you about it later. --- diff --git a/bot.tcl b/bot.tcl index edc249c..8d2083a 100755 --- a/bot.tcl +++ b/bot.tcl @@ -18,7 +18,7 @@ proc sendout {command args} { } set args [lreplace $args 0 -1 $command] set string [join $args { }] - puts "-> $string" + puts "[clock seconds] -> $string" puts $sock $string } @@ -77,11 +77,11 @@ proc onread {args} { ![regexp {^!} [lindex $params 1]]} { # on-channel message, ignore catch { - recordlastseen_p $prefix "talking on [lindex $params 0]" + recordlastseen_p $prefix "talking on [lindex $params 0]" 1 } return } - log "<- $org" + log "[clock seconds] <- $org" set procname msg_$command if {[catch { info body $procname }]} { return } if {[catch { @@ -92,6 +92,14 @@ proc onread {args} { } } +proc msendprivmsg {dest ll} { + foreach l $ll { sendout PRIVMSG $dest $l } +} + +proc msendprivmsg_delayed {delay dest ll} { + after $delay [list msendprivmsg $dest $ll] +} + proc prefix_none {} { upvar 1 p p if {[string length $p]} { error "prefix specified" } @@ -130,14 +138,117 @@ proc prefix_nick {} { if {"[irctolower $n]" == "[irctolower $nick]"} { error "from myself" } } -proc recordlastseen_n {n how} { - global lastseen +proc showinterval {howlong} { + if {$howlong <= 0} { + return {just now} + } elseif {$howlong < 1000} { + return "${howlong}s ago" + } else { + if {$howlong < 1000000} { + set pfx k + set scale 1000 + } else { + set pfx M + set scale 1000000 + } + set value [expr "$howlong.0 / $scale"] + foreach {min format} {100 %.0f 10 %.1f 1 %.2f} { + if {$value < $min} continue + return [format "$format${pfx}s ago" $value] + } + } +} + +proc showtime {when} { + return [showinterval [expr {[clock seconds] - $when}]] +} + +proc def_msgproc {name argl body} { + proc msg_$name "varbase $argl" "\ + upvar #0 msg/\$varbase/dest d\n\ + upvar #0 msg/\$varbase/str s\n\ + upvar #0 msg/\$varbase/accum a\n\ +$body" +} + +def_msgproc begin {dest str} { + set d $dest + set s $str + set a {} +} + +def_msgproc append {str} { + set ns "$s$str" + if {[string length $s] && [string length $ns] > 65} { + msg__sendout $varbase + set s " [string trimleft $str]" + } else { + set s $ns + } +} + +def_msgproc finish {} { + msg__sendout $varbase + unset s + unset d + return $a +} + +def_msgproc _sendout {} { + lappend a [string trimright $s] + set s {} +} + +proc looking_whenwhere {when where} { + set str [showtime [expr {$when-1}]] + if {[string length $where]} { append str " on $where" } + return $str +} + +proc recordlastseen_n {n how here} { + global lastseen lookedfor set lastseen([irctolower $n]) [list $n [clock seconds] $how] + if {!$here} return + upvar #0 lookedfor([irctolower $n]) lf + if {[info exists lf]} { + switch -exact [llength $lf] { + 0 { + set ml {} + } + 1 { + manyset [lindex $lf 0] when who where + set ml [list \ + "FYI, $who was looking for you [looking_whenwhere $when $where]."] + } + default { + msg_begin tosend $n "FYI, people have been looking for you:" + set i 0 + set fin "" + foreach e $lf { + incr i + if {$i == 1} { + msg_append tosend " " + } elseif {$i == [llength $lf]} { + msg_append tosend " and " + set fin . + } else { + msg_append tosend ", " + } + manyset $e when who where + msg_append tosend \ + "$who ([looking_whenwhere $when $where])$fin" + } + set ml [msg_finish tosend] + } + } + unset lf + msendprivmsg_delayed 1000 $n $ml + } } -proc recordlastseen_p {p how} { +proc recordlastseen_p {p how here} { prefix_nick - recordlastseen_n $n $how + recordlastseen_n $n $how $here } proc chanmode_arg {} { @@ -147,11 +258,21 @@ proc chanmode_arg {} { return $rv } +proc chanmode_o1 {m g p chan} { + global nick + prefix_nick + set who [chanmode_arg] + recordlastseen_n $n "being nice to $who" 1 + if {"[irctolower $who]" == "[irctolower $nick]"} { + sendout PRIVMSG $n Thanks. + } +} + proc chanmode_o0 {m g p chan} { global nick chandeop prefix_nick set who [chanmode_arg] - recordlastseen_p $p "being mean to $who" + recordlastseen_p $p "being mean to $who" 1 if {"[irctolower $who]" == "[irctolower $nick]"} { set chandeop($chan) [list [clock seconds] $p] } @@ -169,35 +290,41 @@ proc msg_MODE {p c dest modelist args} { foreach m [split $modelist] { set procname chanmode_$m$give if {[catch { info body $procname }]} { - recordlastseen_p $p "fiddling with $dest" + recordlastseen_p $p "fiddling with $dest" 1 } else { $procname $m $give $p $dest } } } -proc msg_JOIN {p c chan} { recordlastseen_p $p "joining $chan" } -proc msg_PART {p c chan} { recordlastseen_p $p "leaving $chan" } -proc msg_QUIT {p c why} { recordlastseen_p $p "leaving ($why)" } +proc msg_NICK {p c newnick} { + prefix_nick + recordlastseen_n $n "changing nicks to $newnick" 0 + recordlastseen_n $newnick "changing nicks from $n" 1 +} + +proc msg_JOIN {p c chan} { recordlastseen_p $p "joining $chan" 1 } +proc msg_PART {p c chan} { recordlastseen_p $p "leaving $chan" 1 } +proc msg_QUIT {p c why} { recordlastseen_p $p "leaving ($why)" 0 } proc msg_PRIVMSG {p c dest text} { prefix_nick if {[ischan $dest]} { - recordlastseen_n $n "invoking me in $dest" + recordlastseen_n $n "invoking me in $dest" 1 set output $dest } else { - recordlastseen_n $n "talking to me" + recordlastseen_n $n "talking to me" 1 set output $n } if {[catch { regsub {^! *} $text {} text set ucmd [ta_word] - set procname ucmd_[string tolower $ucmd] + set procname ucmd/[string tolower $ucmd] if {[catch { info body $procname }]} { error "unknown command; try help for help" } - $procname + $procname $p $dest } rv]} { sendout PRIVMSG $n "error: $rv" } else { @@ -229,17 +356,20 @@ proc ta_nick {} { return $v } +proc def_ucmd {cmdname body} { + proc ucmd/$cmdname {p dest} " upvar 1 text text\n$body" +} + proc ucmdr {priv pub} { return -code return [list $priv $pub] } -proc ucmd_help {} { - upvar 1 text text +def_ucmd help { ta_nomore ucmdr \ {Commands currently understood: -help -seen } {} +help get this list of commands +seen ask after someone (I'll tell them you asked)} {} } proc manyset {list args} { @@ -249,40 +379,36 @@ proc manyset {list args} { } } -proc ucmd_seen {} { +def_ucmd seen { global lastseen nick - upvar 1 text text - set n [irctolower [ta_nick]] + prefix_nick + set ncase [ta_nick] + set nlower [irctolower $ncase] ta_nomore - if {"$n" == "[irctolower $nick]"} { + set now [clock seconds] + if {"$nlower" == "[irctolower $nick]"} { error "I am not self-aware." - } elseif {![info exists lastseen($n)]} { - ucmdr {} "I've never seen $n." + } elseif {![info exists lastseen($nlower)]} { + set rstr "I've never seen $ncase." } else { - manyset $lastseen($n) realnick time what - set howlong [expr {[clock seconds] - $time}] - if {$howlong <= 0} { - set string now - } elseif {$howlong < 1000} { - set string "${howlong}s ago" - } else { - if {$howlong < 1000000} { - set pfx k - set scale 1000 - } else { - set pfx M - set scale 1000000 - } - set value [expr "$howlong.0 / $scale"] - foreach {min format} {100 %.0f 10 %.1f 1 %.2f} { - if {$value < $min} continue - set string [format "$format${pfx}s ago" $value] - break - } - } - if {![info exists string]} { set string now } - ucmdr {} "I last saw $realnick $string, $what." + manyset $lastseen($nlower) realnick time what + set howlong [expr {$now - $time}] + set string [showinterval $howlong] + set rstr "I last saw $realnick $string, $what." + } + if {[ischan $dest]} { + set where $dest + } else { + set where {} + } + upvar #0 lookedfor($nlower) lf + if {[info exists lf]} { set oldvalue $lf } else { set oldvalue {} } + set lf [list [list $now $n $where]] + foreach v $oldvalue { + if {"[irctolower [lindex $v 1]]" == "[irctolower $n]"} continue + lappend lf $v } + ucmdr {} $rstr } if {![info exists sock]} {