#--------------------------------------------------------------------- # lusers.tcl # Tcl script for IRC bot eggdrop # # Usage: !lusers # The bot will send a LUSERS request to the server and report the # result in the channel. # # v0: 24-Oct-2002 # v1: 26-Oct-2002 # v2: 28-Oct-2002 #--------------------------------------------------------------------- package require eggdrop 1.6 package require Tcl 8.0 bind pub o !lusers lusers:pub bind time - * lusers:time bind RAW - 251 lusers:raw bind RAW - 252 lusers:raw bind RAW - 253 lusers:raw bind RAW - 254 lusers:raw bind RAW - 255 lusers:raw #--------------------------------------------------------------------- # Publicly triggered "LUSERS" request. #--------------------------------------------------------------------- proc lusers:pub { nick uhost hand chan text } { global lusersinfo global lusersrawinfo # use lowercase channel name only in the remainder. set chantlw [string tolower $chan] # if lusersinfo exists a lusers request is already pending. if {[info exists lusersinfo]} { # check if a request is already pending for that channel. if {[lsearch -exact $lusersinfo $chantlw] == -1 } { # add the channel to channels where bot will report. lappend lusersinfo $chantlw } return 1 } # Send with some delay a new lusers request. utimer 5 {puthelp LUSERS} lappend lusersinfo [unixtime] $chantlw # putlog the request. return 1 } #--------------------------------------------------------------------- # On a regular basis check the pending request. #--------------------------------------------------------------------- proc lusers:time { min hour day month year } { global lusersinfo global lusersrawinfo if {![info exists lusersinfo]} { return } set timestamp [lindex $lusersinfo 0] if {[expr [unixtime] - $timestamp] < 120 } { return } # request expired. lusers:report } #--------------------------------------------------------------------- # RAW results. #--------------------------------------------------------------------- proc lusers:raw { server keyword text } { global lusersinfo global lusersrawinfo # currently a lusers request pending? if {![info exists lusersinfo]} { return 0 } # numerics must be in 251-255 range if {![string match {25[1-5]} $keyword]} { return 0 } # remove the botnick from the result. if {[scan $text "%s %\[^\n\]" botnick text ] != 2 } { return 0 } # awkward... regsub -all : $text "" text # lappend the remaining text to the list. lappend lusersrawinfo $text # retrieve total amount of users from raw 251 if { $keyword == 251 } { set scanrule {There are %d users and %d invisible} if {[scan $text $scanrule vusers iusers] == 2 } { set totalusers [expr $vusers + $iusers] lappend lusersrawinfo "(total $totalusers users)" } } # numeric 255 (last) reached? if { $keyword != 255 } { return 0 } lusers:report } #--------------------------------------------------------------------- # On an expired request or a 255 RAW numeric, report results # and unset the lists lusersinfo and lusersrawinfo. #--------------------------------------------------------------------- proc lusers:report { } { global lusersinfo global lusersrawinfo global server # review the raw info. if {![info exists lusersrawinfo]} { set lusersrawinfo [list] } set line [join $lusersrawinfo ". "] # if line is empty: something is wrong. if { $line == "" } { set line "Sorry, could not obtain lusers info." } # retrieve the name of the server set scanrule {%[^:]:%s} if {[scan $server $scanrule servername serverport] < 1 } { set servername "current server" } set date [ctime [unixtime]] set line "\002Lusers info on $servername ($date)\002: $line." # spit out the line on all requestchannels. set channels [lrange $lusersinfo 1 end] foreach chan $channels { if { ![botonchan $chan] } { continue } puthelp "PRIVMSG $chan :$line" } unset lusersinfo unset lusersrawinfo } putlog "Loaded (version 2): Lusers."