X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~mdw/git/ircbot/blobdiff_plain/83dd12243f89e23ca1ddf90da9a55964b3b963b2..7ce72032518e164fbcef80ed0c3b20b91a1a9d26:/bot.tcl diff --git a/bot.tcl b/bot.tcl index 8d2083a..54cda63 100755 --- a/bot.tcl +++ b/bot.tcl @@ -2,7 +2,7 @@ set host chiark set port 6667 -set nick Blight +if {![info exists nick]} { set nick Blight } proc sendout {command args} { global sock @@ -49,6 +49,7 @@ proc onread {args} { global sock if {[gets $sock line] == -1} { set terminate 1; return } +binary scan $line H* inhex; puts >$inhex< regsub -all "\[^ -\176\240-\376\]" $line ? line set org $line if {[regexp -nocase {^:([^ ]+) (.*)} $line dummy prefix remain]} { @@ -92,13 +93,12 @@ 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 sendprivmsg {dest l} { + sendout [expr {[ischan $dest] ? "PRIVMSG" : "NOTICE"}] $dest $l } +proc sendaction {dest what} { sendout PRIVMSG $dest "\001ACTION $what\001" } +proc msendprivmsg {dest ll} { foreach l $ll { sendprivmsg $dest $l } } +proc msendprivmsg_delayed {delay dest ll} { after $delay [list msendprivmsg $dest $ll] } proc prefix_none {} { upvar 1 p p @@ -138,11 +138,9 @@ proc prefix_nick {} { if {"[irctolower $n]" == "[irctolower $nick]"} { error "from myself" } } -proc showinterval {howlong} { - if {$howlong <= 0} { - return {just now} - } elseif {$howlong < 1000} { - return "${howlong}s ago" +proc showintervalsecs {howlong} { + if {$howlong < 1000} { + return "${howlong}s" } else { if {$howlong < 1000000} { set pfx k @@ -154,11 +152,19 @@ proc showinterval {howlong} { 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] + return [format "$format${pfx}s" $value] } } } +proc showinterval {howlong} { + if {$howlong <= 0} { + return {just now} + } else { + return "[showintervalsecs $howlong] ago" + } +} + proc showtime {when} { return [showinterval [expr {[clock seconds] - $when}]] } @@ -264,7 +270,7 @@ proc chanmode_o1 {m g p chan} { set who [chanmode_arg] recordlastseen_n $n "being nice to $who" 1 if {"[irctolower $who]" == "[irctolower $nick]"} { - sendout PRIVMSG $n Thanks. + sendprivmsg $n Thanks. } } @@ -326,11 +332,17 @@ proc msg_PRIVMSG {p c dest text} { } $procname $p $dest } rv]} { - sendout PRIVMSG $n "error: $rv" + sendprivmsg $n "error: $rv" } else { - foreach {td val} [list $n [lindex $rv 0] $output [lindex $rv 1]] { + manyset $rv priv_msgs pub_msgs priv_acts pub_acts + foreach {td val} [list $n $priv_msgs $output $pub_msgs] { + foreach l [split $val "\n"] { + sendprivmsg $td $l + } + } + foreach {td val} [list $n $priv_acts $output $pub_acts] { foreach l [split $val "\n"] { - sendout PRIVMSG $td $l + sendaction $td $l } } } @@ -360,16 +372,17 @@ 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 ucmdr {priv pub args} { + return -code return [concat [list $priv $pub] $args] } def_ucmd help { ta_nomore ucmdr \ {Commands currently understood: -help get this list of commands -seen ask after someone (I'll tell them you asked)} {} +help get this list of commands +seen ask after someone (I'll tell them you asked) +summon invite a logged-on user onto IRC} {} } proc manyset {list args} { @@ -379,6 +392,49 @@ proc manyset {list args} { } } +def_ucmd summon { + set target [ta_word] + ta_nomore + if { + [string length $target] > 8 || + [regexp {[^-0-9a-z]} $target] || + ![regexp {^[a-z]} $target] + } { error "invalid username" } + prefix_nick + + upvar #0 lastsummon($target) ls + set now [clock seconds] + if {[info exists ls]} { + set interval [expr {$now - $ls}] + if {$interval < 30} { + ucmdr {} \ + "Please be patient; $target was summoned only [showinterval $interval]." + } + } + regsub {^[^!]*!} $p {} path + if {[catch { + exec userv --timeout 3 $target irc-summon $n $path \ + [expr {[ischan $dest] ? "$dest" : ""}] \ + < /dev/null + } rv]} { + regsub -all "\n" $rv { / } rv + error $rv + } + if {[regexp {^problem (.*)} $rv dummy problem]} { + ucmdr {} "$target $problem." + } elseif {[regexp {^ok ([^ ]+) ([0-9]+)$} $rv dummy tty idlesince]} { + set idletime [expr {$now - $idlesince}] + set ls $now + ucmdr {} {} {} "invites $target ($tty[expr { + $idletime > 10 ? ", idle for [showintervalsecs $idletime]" : "" + }]) to [expr { + [ischan $dest] ? "join us here" : "talk to you" + }]." + } else { + error "unexpected response from userv service: $rv" + } +} + def_ucmd seen { global lastseen nick prefix_nick