From: ijackson Date: Tue, 15 Aug 2000 13:02:14 +0000 (+0000) Subject: Can do "seen" now. X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=0d061d3caa3f3704380c8dbe7ded193a0f616fe7;p=ircbot.git Can do "seen" now. --- diff --git a/bot.tcl b/bot.tcl index 1e4d948..edc249c 100755 --- a/bot.tcl +++ b/bot.tcl @@ -76,6 +76,9 @@ proc onread {args} { [regexp {^[&#+!]} [lindex $params 0]] && ![regexp {^!} [lindex $params 1]]} { # on-channel message, ignore + catch { + recordlastseen_p $prefix "talking on [lindex $params 0]" + } return } log "<- $org" @@ -104,26 +107,182 @@ proc check_nick {n} { if {[regexp {^[-0-9]} $n]} { error "bad nick start" } } +proc ischan {dest} { + return [regexp {^[&#+!]} $dest] +} + +proc irctolower {v} { + foreach {from to} [list "\\\[" "{" \ + "\\\]" "}" \ + "\\\\" "|" \ + "~" "^"] { + regsub -all $from $v $to v + } + return [string tolower $v] +} + proc prefix_nick {} { global nick upvar 1 p p upvar 1 n n if {![regexp {^([^!]+)!} $p dummy n]} { error "not from nick" } check_nick $n - if {"[string tolower $n]" == "$nick"} { error "from myself" } + if {"[irctolower $n]" == "[irctolower $nick]"} { error "from myself" } +} + +proc recordlastseen_n {n how} { + global lastseen + set lastseen([irctolower $n]) [list $n [clock seconds] $how] +} + +proc recordlastseen_p {p how} { + prefix_nick + recordlastseen_n $n $how +} + +proc chanmode_arg {} { + upvar 2 args cm_args + set rv [lindex $cm_args 0] + set cm_args [lreplace cm_args 0 0] + return $rv +} + +proc chanmode_o0 {m g p chan} { + global nick chandeop + prefix_nick + set who [chanmode_arg] + recordlastseen_p $p "being mean to $who" + if {"[irctolower $who]" == "[irctolower $nick]"} { + set chandeop($chan) [list [clock seconds] $p] + } } +proc msg_MODE {p c dest modelist args} { + if {![ischan $dest]} return + if {[regexp {^\-(.+)$} $modelist dummy modelist]} { + set give 0 + } elseif {[regexp {^\+(.+)$} $modelist dummy modelist]} { + set give 1 + } else { + error "invalid modelist" + } + foreach m [split $modelist] { + set procname chanmode_$m$give + if {[catch { info body $procname }]} { + recordlastseen_p $p "fiddling with $dest" + } 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_PRIVMSG {p c dest text} { prefix_nick - if {[regexp {^[&#+!]} $dest]} { - set what "!..." - set them it + if {[ischan $dest]} { + recordlastseen_n $n "invoking me in $dest" + set output $dest } else { - set what "private messages" - set them them + recordlastseen_n $n "talking to me" + set output $n + } + + if {[catch { + regsub {^! *} $text {} text + set ucmd [ta_word] + set procname ucmd_[string tolower $ucmd] + if {[catch { info body $procname }]} { + error "unknown command; try help for help" + } + $procname + } rv]} { + sendout PRIVMSG $n "error: $rv" + } else { + foreach {td val} [list $n [lindex $rv 0] $output [lindex $rv 1]] { + foreach l [split $val "\n"] { + sendout PRIVMSG $td $l + } + } + } +} + +proc ta_nomore {} { + upvar 1 text text + if {[string length $text]} { error "too many parameters" } +} + +proc ta_word {} { + upvar 1 text text + if {![regexp {^([^ ]+) *(.*)} $text dummy firstword text]} { + error "too few parameters" + } + return $firstword +} + +proc ta_nick {} { + upvar 1 text text + set v [ta_word] + check_nick $v + return $v +} + +proc ucmdr {priv pub} { + return -code return [list $priv $pub] +} + +proc ucmd_help {} { + upvar 1 text text + ta_nomore + ucmdr \ +{Commands currently understood: +help +seen } {} +} + +proc manyset {list args} { + foreach val $list var $args { + upvar 1 $var my + set my $val + } +} + +proc ucmd_seen {} { + global lastseen nick + upvar 1 text text + set n [irctolower [ta_nick]] + ta_nomore + if {"$n" == "[irctolower $nick]"} { + error "I am not self-aware." + } elseif {![info exists lastseen($n)]} { + ucmdr {} "I've never seen $n." + } 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." } - sendout PRIVMSG $n \ - "I will respond to $what at some point; for now I just log $them." } if {![info exists sock]} {