# peak.tcl

set peakv "23may97"

#   Shows the peak usage of a given channel, optionally listing the
#   users at that time
#
# Originally: zpeak.tcl
#
# - 10feb97: by zarni <zarni@weirdness.com>
# - 23may97: by Ernst <ernst@studbox.uni-stuttgart.de>
#            Ernst's eggdrop page:  http://www.sodre.net/ernst/eggdrop/
#            - changed name to "peak"
#            - multi-channel support (egg1.0)
#            - sorts peak userlist alfabetically
#            - added '.peak' to DCC
#            - added '.peak reset #channel'
#            - added timezone var
#            - don't save [ctime [unixtime]] but "[date] at [time] $timezone"
#              (because I feel better this way :)
#            - changed putserv to puthelp (because thats the way it should be)
#            - changed PRIVMSG to NOTICE (because it's a bot) (configurable)
#            - some other things I don't remember
#

# -- here you can change some things... ---------------------------------------

# files to be created to store peak info ($peakfile.#channel)
set peakfile ".peakfile"

# timezone your bot sits in
if {![info exists timezone]} {
	set timezone "GMT-03"
}

# flag required to use '!peak' in a channel
set pubpeakflag o

# flag required to use '.peak reset'
set resetpeakflag m

# answer to queries via PRIVMSG? (1 = PRIVMSG,  0 = NOTICE)
set peak_privmsg 0

# show the nicks of the users on the channel at the peak time?
# the nicks are always saved so you can toggle at any time.
set shownicks 1

# -- and here comes the script ------------------------------------------------

if {$peak_privmsg} {set peakout "PRIVMSG"} {set peakout "NOTICE"}

# Little proc to compare string ignoring case, used in sorting
proc icompare {arg1 arg2} { return [string compare [string tolower $arg1] [string tolower $arg2]] }

# Loads peak data or resets it
proc load_peak { arg } {
	# load_peak #chan         - Resets channel
	# load_peak reset         - Resets all
	# load_peak anything else - Loads everything
	global peakfile peak timezone
	if {[string index $arg 0] == "#"} {
		set chanlist [lindex $arg 0]
		if {[file exists ${peakfile}.$chanlist]} { file delete ${peakfile}.$chanlist }
	} {
		set chanlist [channels]
		if {[string tolower $arg] == "reset"} {
			foreach chan $chanlist {
				if {[file exists ${peakfile}.$chan]} { file delete ${peakfile}.$chan }
			}
		}
	}
	foreach chan $chanlist {
		set chan [string tolower $chan]
		if {[file exists ${peakfile}.$chan]} {
			set in [open ${peakfile}.$chan r]
			set peak(nicks!$chan) [lsort -command icompare [gets $in]]
			set peak(peak!$chan) [llength $peak(nicks!$chan)]
			set peak(date!$chan) [gets $in]
			close $in
		} {
			set peak(peak!$chan) [llength [chanlist $chan]]
			set peak(date!$chan) "[date] at [time] $timezone"
			set peak(nicks!$chan) [lsort -command icompare [chanlist $chan]]
		}
	}
}

# On join, check number of users and save it, if it is a peak
proc join_peak {nick userhost handle channel} {
	global peakfile peak timezone
	set channel [string tolower $channel]
	set onchannel [llength [chanlist $channel]]
	if {![info exist peak(peak!$channel)]} {
		if {[file exists ${peakfile}.$channel]} {
			set in [open ${peakfile}.$channel r]
			set peak(nicks!$channel) [lsort -command icompare [gets $in]]
			set peak(peak!$channel) [llength $peak(nicks!$channel)]
			set peak(date!$channel) [gets $in]
			close $in
		} {
			set peak(peak!$channel) $onchannel
			set peak(date!$channel) "[date] at [time] $timezone"
			set peak(nicks!$channel) [lsort -command icompare [chanlist $channel]]
		}
	}
	if {$onchannel >= $peak(peak!$channel)} {
		set peak(peak!$channel) $onchannel
		set peak(date!$channel) "[date] at [time] $timezone"
		set peak(nicks!$channel) [lsort -command icompare [chanlist $channel]]
		set out [open ${peakfile}.$channel w]
		puts $out $peak(nicks!$channel)
		puts $out $peak(date!$channel)
		close $out
	}
}

# Answer to private peak-queries via NOTICEs
proc msg_peak {nick userhost handle args} {
	global peak shownicks peakout
	set channel [string tolower [lindex $args 0]]
	if {$channel == ""} {
		puthelp "$peakout $nick :Usage: 'peak <channel>'"
	} {
		puthelp "$peakout $nick :Peak statistics for $channel."
		puthelp "$peakout $nick :Peaked at \002$peak(peak!$channel)\002 users on \002$peak(date!$channel)\002 "
		if {$shownicks == 1} {
			puthelp "$peakout $nick :Users present: $peak(nicks!$channel)"
		}
	}
}

# Answer to peak-queries via PUBLIC message
proc pub_peak {nick userhost handle channel args} {
	global peak shownicks peakout
	set channel [string tolower $channel]
	puthelp "$peakout $channel :Peak statistics for $channel."
	puthelp "$peakout $channel :Peaked at \002$peak(peak!$channel)\002 users on \002$peak(date!$channel)\002"
	if {$shownicks == 1} {
		puthelp "$peakout $channel :Users present: $peak(nicks!${channel})"
	}
}

# Answer to peak-queries via DCC (or to reset peak data)
proc dcc_peak {hand idx arg} {
	global peak shownicks resetpeakflag
	set channel [string tolower [lindex $arg 0]]
	if {$channel == "reset"} {
		if {[matchattr $hand $resetpeakflag]} {
			set chan [string tolower [lindex $arg 1]]
			if { $chan == "all" } {
				putdcc $idx "Reseting all peak statistics."
				load_peak reset
				return 1
			} elseif {[string index $chan 0] == "#"} {
				putdcc $idx "Reseting peak statistics for $chan."
				load_peak $chan
				return 1
			} else {
				putdcc $idx "Reseting peak statistics for [lindex [console $idx] 0]."
				load_peak [lindex [console $idx] 0]
				return 1
			}
		} {
			putdcc $idx "You have no access to this."
		   	return 0
		}
	} {
		if {$channel == ""} { set channel [lindex [console $idx] 0]	}
		if {[lsearch [array names peak] peak!$channel] == -1} {
			putdcc $idx "No peak statistics for $channel avaliable."
			return 0
		} {
			putdcc $idx "Peak statistics for $channel."
			putdcc $idx "Peaked at $peak(peak!$channel) users on $peak(date!$channel) "
			if {$shownicks == 1} {
				putdcc $idx "Users present: $peak(nicks!$channel)"
			}
			return 1
		}
	}
}

bind join - * join_peak
bind msg - peak msg_peak
bind pub $pubpeakflag !peak pub_peak
bind dcc - peak dcc_peak

# Sets variables when loading
foreach c [channels] {
	set chan [string tolower $c]
	if {![info exists peak(peak!${chan})]} { set peak(peak!${chan}) 0 }
	if {![info exists peak(date!${chan})]} { set peak(date!${chan}) "" }
	if {![info exists peak(nicks!${chan})]} { set peak(nicks!${chan}) "" }
}

# Loads current peak statistics for active channels
load_peak load

putlog "- Peak (v$peakv) by zarni and Ernst loaded"
