# Random commands for sbnc
# Copyright (C) 2008 Khobbits
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

###############################################################################
############## You shouldn't NEED to edit anything in this file. ##############
### I don't recall where but the showusers command I stole from somewhere. ####
#### su's tag/settag doesnt list applicable tags, just gives suggestions. #####
###############################################################################

internalbind command kh:com

proc kh:com {client parameters} {

	set command [lindex $parameters 0]

	if {[string equal -nocase $command "help"]} {
		if {[getbncuser $client admin]} {
			set help "Syntax: su <user> <command> \[values/params\]\n
				Commands:
				raw <params> - sends the raw text to the server
				disconnect - disconnects user
				reconnect - reconnects user if disconnected
				jump - reconnect user
				set <setting> <value> - sets a user setting - see note below
				value <setting> - returns a user setting - see note below
				settag <setting> <value> - sets a 'tag' setting on a user - see note below
				tag <setting> - returns a 'tag' setting on user - see note below
				log - plays users log file
				eraselog - erases their user log
				addhost <value> - adds an connection host
				delhost <value> - removes a connection host
				clearhosts - wipes connection host list
				hosts - shows connection host list
				traffic - displays user traffic
				Values: connected (to server), onbnc, nick, seen, network, channels, uptimehr
				Channnel values: chanmode <chan>, topic <chan>, chanlist <chan>, usercount <chan>
				Note: set/value/settag/tag have specific sets of settings, to view these lists use the command without leaving setting null."

			bncaddcommand "su" "KHAdmin" "Admin overide commands" $help
			bncaddcommand "msu" "KHAdmin" "Performs a mass su on all accounts" "Syntax: msu <command> \[values/params\]\nThis command has the same syntax and commands as su, except it will automatically replace the user feild, so skip it.\nUse /sbnc help su for a command list."
			bncaddcommand "lastused" "KHAdmin" "Shows a list of last used times"
		} elseif {[getbncuser $client tag reseller] == "1"} {
			bncaddcommand "lastused" "KHAdmin" "Shows a list of last used times"
			bncaddcommand "disconnect" "KHUser" "Disconnects from server"
		} else {
			bncaddcommand "disconnect" "KHUser" "Disconnects from server"
		}
	}

	if {[getbncuser $client admin]} {
		if {[string equal -nocase $command "su"]} { khz:su $client $parameters }
		if {[string equal -nocase $command "msu"]} { khz:msu $client $parameters }
		if {[string equal -nocase $command "lastused"]} { khz:lastused $client $parameters }
				if {[string equal -nocase $command "simul"]} { admin:log $client "Simul'd [lindex $parameters 1]: [lrange $parameters 2 4]..." }
	} elseif {[getbncuser $client tag reseller] == "1"} {
		if {[string equal -nocase $command "lastused"]} { khz:lastused $client $parameters }
		if {[string equal -nocase $command "disconnect"]} { bncdisconnect $client; haltoutput; }
	} else {
		if {[string equal -nocase $command "disconnect"]} { bncdisconnect $client; haltoutput; }
	}
	if {[string equal -nocase $command "eggdcc"]} { fakedcc $client $parameters }
}

proc khz:lastused {client parameters} {
	set y [lindex $parameters 1]
	if {[catch {expr int($y)}]} { set y -1 }
	if ([getbncuser $client admin]) {
		foreach x [bncuserlist] {
			if { [getbncuser $x seen] != 0 } {
				if { [expr ( [clock seconds] - [getbncuser $x seen] ) /86400.0 ] > $y } {
						bncreply "$x last logged in [duration [expr [clock seconds] - [getbncuser $x seen]]]days ago"
				}
			} else {
				bncreply "$x has never logged in"
			}
		}
	} elseif {[getbncuser $client tag reseller] == "1"} {
		foreach x [bncuserlist] {
			if {[string equal -nocase [virtual:getgroup $x] [virtual:getgroup $client]]} {
				if { [getbncuser $x seen] != 0 } {
					if { [expr ( [clock seconds] - [getbncuser $x seen] ) /86400.0 ] > $y } {
							bncreply "$x last logged in [duration [expr [clock seconds] - [getbncuser $x seen]]]days ago"
					}
				} else {
					bncreply "$x has never logged in"
				}
			}
		}
	}
	haltoutput
  return
}

proc khz:msu {client arg} {
	foreach user [bncuserlist] {
		khz:su $client "su $user [join [lrange $arg 1 end]]"
	}
	haltoutput
	return
}

proc khz:su {client parameters} {

		catch {su [join [lrange $parameters 1 end]]} result

		if {$result == ""} { set result "<null>" }
		foreach sline [split $result \n] {
			bncreply "$sline"
		}
		haltoutput
	return
}

proc su {parameters} {
	variable ctx [getctx]

	set user [lindex $parameters 0]

	catch {lsearch -inline -regex [bncuserlist] "(?i)^${user}$"} result
	if {$result != ""} {
		set user $result
	} else {
		return "No such user. Syntax: su <user> <command> \[values/params\]. see /sbnc help su for more information."
	}

	set command [lindex $parameters 1]
	set params [join [lrange $parameters 2 end]]
	setctx $user
	set result ""
	switch -- $command {
		raw {
			puthelp [join $params]
			set result "RAW: [join $params]"
		}
		disconnect {
			bncdisconnect [join [lrange $params 0 end]]
			set result "Disconnecting for \"[join [lrange $params 0 end]]\""
		}
		reconnect {
			if {![getbncuser $user hasserver]} {
				jump
				set result "Reconnecting!"
			} else {
				set result "Connected to server..."
			}
		}
		connected {
			if {![getbncuser $user hasserver]} {
				set result "Not connected to irc server."
			} else {
				set result "Connected to irc server."
			}
		}
		onbnc {
			if {![getbncuser $user hasclient]} {
				set result "Not connected to bnc."
			} else {
				set result "Connected to bnc."
			}
		}
		nick {
			set result $::botnick
		}
		value {
			if {[lsearch -exact [list server port serverpass client realname nick awaynick away uptime lock admin hasserver hasclient vhost channels tag delayjoin seen appendts quitasaway automodes dropmodes suspendreason sslclient realserver ident] [lindex $params 0]] == -1} {
				set result "Not a valid setting. Settings: server port serverpass client realname nick awaynick away uptime lock admin hasserver hasclient vhost channels tag delayjoin seen appendts quitasaway automodes dropmodes suspendreason sslclient realserver ident"
			} else {
				set result [getbncuser $user [lindex $params 0]]
			}
		}
		tag {
			if {[lindex $params 0] == ""} {
				set result "Seems you didnt supply a tag, try: nickserv.nick nickserv.reply nickserv.warning amsg_enable amsg_channel amsg_counter awaymessage"
			} else {
				set result [getbncuser $user tag [lindex $params 0]]
			}
		}
		settag {
			if {[lindex $params 0] == ""} {
				set result "Seems you didnt supply a tag, try: nickserv.nick nickserv.password nickserv.reply nickserv.warning amsg_enable amsg_channel amsg_counter awaymessage"
			} else {
				setbncuser $user tag [lindex $params 0] [join [lrange $params 1 end]]
				set result 1
			}
		}
		network {
			set result [getisupport NETWORK]
		}
		channels {
			set result [join [internalchannels]]
		}
		uptimehr {
			set result [duration [getbncuser $user uptime]]
		}
		traffic {
			set result "Server in: [trafficstats $user server in]Bytes Server out: [trafficstats $user server out]Bytes Client in: [trafficstats $user client in]Bytes Client out: [trafficstats $user client out]Bytes"
		}
		chanmode {
			set result [getchanmode [lindex $params 0]]
		}
		topic {
			set result [topic [lindex $params 0]]
		}
		chanlist {
			set result [join [internalchanlist [lindex $params 0]]]
		}
		usercount {
			set result [llength [internalchanlist [lindex $params 0]]]
		}
		jump {
			jump
			set result "Jumping!"
		}
		set {
			if {[lsearch -exact [list server port serverpass realname nick awaynick away lock admin channels tag vhost delayjoin password appendts quitasaway automodes dropmodes suspendreason ident] [lindex $params 0]] == -1} {
				set result "Not a valid setting. Settings: server port serverpass realname nick awaynick away lock admin channels tag vhost delayjoin password appendts quitasaway automodes dropmodes suspendreason ident"
			} else {
				setbncuser $user [lindex $params 0] [join [lrange $params 1 end]]
				set result 1
			}
		}
		log {
			set error [catch "open users/$user.log r" file]
			if {$error} {
				set result "Log could not be opened (user is case sensitive)"
			} else {
				set stuff [read $file]
				close $file
				set result "${stuff}\nsu $user $command - Log end."
			}
		}
		eraselog {
			set file [open users/$user.log w+]
			close $file
		}
		addhost {
			if {[addbnchost [lindex $params 0]] == 1} {
				set result "Added host [lindex $params 0]"
			} else {
				set result "Failed to add host [lindex $params 0]"
			}
		}
		delhost {
			delbnchost [lindex $params 0]
			set result "Deleted host [lindex $params 0]"
		}
		clearhosts {
			set hostclear [getbnchosts]
			foreach hosts [getbnchosts] {
				delbnchost $hosts

			}
			set result "Cleared hosts: $hostclear"
		}
		hosts {
			set result [join [getbnchosts]]
		}
		seen {
			set result "Time since last login: [duration [expr [clock seconds] - [getbncuser $user seen]]]"
		}
		default {
		set result "Syntax: su <user> <command> \[values/params\]
		/sbnc help su for more information and a list of valid commands."
		}
	}
	admin:log $ctx "Used su $user $command - [lrange [split $result] 0 3]..."
	setctx $ctx
	return "su $user $command - $result"
}

proc admin:log {client text} {
	foreach x [bncuserlist] {
		if {[getbncuser $x admin]} {
		setctx $x
			if {[getbncuser $x hasclient]} {
				putclient ":-sBNC!core@shroudbnc.org PRIVMSG $x :\[Admin log\] $client: $text"
			}
			putlog "\[Admin log\] $client: $text"
		}
	}
}

proc fakedcc {client text} {
	global botnick
	if {[llength $text] < 4} {
		bncreply "This command lets you fake DCC incoming headers.  Party will be informed via /ctcp <target> chat"
		bncreply "Syntax: <nick> [address] <longip> <port>"
	}
	if {[llength $text] == 4} {
		set text [linsert $text 2 "a@b.c"]
	}
	putserv "privmsg [lindex $text 1] \001chat\001"
	putclient "\:[lindex $text 1]![lindex $text 2] PRIVMSG $botnick \:\001DCC CHAT chat [lindex $text 3] [lindex $text 4]\001"
	haltoutput
	return 0
}
