[regexp {^[&#+!]} [lindex $params 0]] &&
![regexp {^!} [lindex $params 1]]} {
# on-channel message, ignore
+ catch {
+ recordlastseen_p $prefix "talking on [lindex $params 0]"
+ }
return
}
log "<- $org"
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 <nick>} {}
+}
+
+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]} {