# shroudBNC - an object-oriented framework for IRC
# Copyright (C) 2005 Gunnar Beutner
#
# Modified by 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.

internalbind client sbnc:partyline
internalbind attach sbnc:partyattach
internalbind detach sbnc:partydetach
internalbind usrdelete sbnc:partysync
internalbind command sbnc:partycom
internalbind svrlogon sbnc:versionfix

#######################################################################
#### Edit this line for the partyline channels that you would like ####
####### Oh and you will probably want to edit the default host. #######
#######################################################################

set ::partyline [list ~kh ~support]

set ::partynopart [list ~kh]

set ::partyhost "sBNC.KHobbits.net"


set ::partyban(-sbnc,-sbnc) 1

if {![info exists ::partytopic]} {
	foreach chan $::partyline {
		set ::partytopic($chan) "shroudBNC Partyline"
		set ::partyts($chan) [unixtime]
		set ::partywho($chan) "-sBNC"
	}
}

proc sbnc:partycom {client parameters} {
	set command [lindex $parameters 0]
	if {[string equal -nocase $command "help"]} {
		if {[getbncuser $client admin]} {
			set help "Syntax: partyline <user> <command> \[values/params\]\n
				Commands:
				join <chan> - same as the user typing /join <chan>
				part <chan> - same as the user typing /part <chan>
				set <chan1,chan2,chan3> - sets the partyline channels the user is on
				show - lists the partyline channels the user is on
				kick <chan> - kicks this user from the partyline channel
				ban <chan> - prevents a user from rejoining the channel
				unban <chan> - undoes the above action
				add <chan> - adds a partyline channel untill rehash (not user related)
				del <chan> - removes a perm partyline untill rehash, or removes temp partyline
				sync - Removes disconnected users from the partyline"

			bncaddcommand "partyline" "KHAdmin" "Allows the admin of the partyline channels" $help
			bncaddcommand "mpartyline" "KHAdmin" "Allows mass admin of the partyline channels" "Syntax: mpartyline <command> \[values/params\]\nThis command has the same syntax and commands as partyline, except it will automatically replace the user feild, so skip it.\nUse /sbnc help partyline for a command list."
		}

	}
	if {![getbncuser $client admin]} { return }
	if {[string equal -nocase $command "partyline"]} { khz:partycommands $client $parameters }
	if {[string equal -nocase $command "mpartyline"]} { khz:mpartycommands $client $parameters }
}

proc khz:mpartycommands {client arg} {
	foreach user [bncuserlist] {
		khz:partycommands $client "partyline $user [join [lrange $arg 1 end]]"
	}
	haltoutput
	return
}

proc khz:partycommands {client parameters} {

	if { [string equal -nocase "partyline" [lindex $parameters 0]] && [getbncuser $client admin] } {
		catch {partyline [join [lrange $parameters 1 end]]} result

		if {$result == ""} { set result "<null>" }
		foreach sline [split $result \n] {
			bncreply "$sline"
		}
		haltoutput
	}
	return
}

proc partyline {parameters} {
  global partyban botnick partyline botname partyhost

	variable ctx [getctx]

	set user [lindex $parameters 0]
	set command [lindex $parameters 1]
	set params [join [lrange $parameters 2 end]]

	setctx $user
	set result ""
	switch -- $command {
		join {
			sbnc:partyline $user "join [lindex $params 0]"
			set result 1
		}
		part {
			sbnc:partyline $user "part [lindex $params 0] :Parted by admin."
			set result 1
		}
		kick {
			set chans [split [string tolower [getbncuser $user tag partyline]] ","]
			set idx [lsearch $chans [string tolower [lindex $params 0]]]
			if {$idx != -1} {
				setbncuser $user tag partyline [join [lreplace $chans $idx $idx] ","]
				putclient ":-sBNC!core@shroudbnc.org KICK [lindex $params 0] $botnick :Kicked by admin."
				sbnc:bcpartybutone $user ":-sBNC!core@shroudbnc.org KICK [lindex $params 0] -$user :Kicked by admin."
			}
			set result 1
		}
		set {
			setbncuser $user tag partyline "[join [string tolower [lindex $params 0]] ","]"
			set result "$user is now on: [split [string tolower [getbncuser $user tag partyline]] ","]"
		}
		show {
			set result "$user is on: [split [string tolower [getbncuser $user tag partyline]] ","]"
		}
		sync {
			set chans [split [string tolower [getbncuser $user tag partyline]] ","]
			foreach chan $partyline {
				if {[lsearch $chans [string tolower $chan]] == -1} {
					sbnc:bcpartybutone $user ":-$user!user@$partyhost PART $chan :Resyncing BNC: User isnt on channel."
				}
				if {[lsearch $chans [string tolower $chan]] != -1 && ![getbncuser $user hasclient]} {
					sbnc:bcpartybutone $user ":-$user!user@$partyhost PART $chan :Resyncing BNC: User isnt connected to BNC."
				}
				if {[lsearch $chans [string tolower $chan]] != -1 && [getbncuser $user hasclient]} {
					sbnc:partyline $user "join $chan 1"
				}
			}
		}
		ban {
			set partyban([lindex $params 0],$user) 1
			set result 1
		}
		unban {
			unset partyban([lindex $params 0],$user)
			set result 1
		}
		add {
			lappend partyline [lindex $params 0]
			set result 1
		}
		del {
			set idx [lsearch [string tolower $partyline] [string tolower [lindex $params 0]]]
			set partyline [lreplace $partyline $idx $idx]

			foreach x [bncuserlist] {
				set chans [split [string tolower [getbncuser $x tag partyline]] ","]
				set idx [lsearch $chans [string tolower [lindex $params 0]]]
				if {$idx != -1} {
					setctx $x
					putclient ":$botnick PART [lindex $params 0]"
					setbncuser $x tag partyline [join [lreplace $chans $idx $idx] ","]
				}
			}
			set result 1
		}
		default {
			setctx $ctx
			set result "Syntax: partyline <user> <command> \[values/params\]
			/sbnc help partline for more information and a list of valid commands."
		}
	}
	setctx $ctx
	return "partyline $user $command - $result"
}

proc sbnc:partyline {client parameters} {
	setctx $client

	global botnick botname server partyline partytopic partyts partywho partyban partyhost partynopart

	set cmd [lindex $parameters 0]
	set chan [string tolower [lindex $parameters 1]]
	set serv [lindex [split $server ":"] 0]
	set chans [split [string tolower [getbncuser $client tag partyline]] ","]

	if {[string equal -nocase "version" $cmd]} {
	utimer 2 "setctx $client; putclient \":$serv 005 $botnick CHANTYPES=[getisupport chantypes]~ :are supported by this server.\""
	}

	if {[lsearch [string tolower $partyline] [string tolower [lindex $parameters 1]]] == -1} {
	if [string match {-*} [string tolower [lindex $parameters 1]]] {
		sbnc:privateparty $client $parameters
	}
		return
	}
	haltoutput

	if {![info exists ::partytopic($chan)]} {
		set ::partytopic($chan) "shroudBNC Partyline"
		set ::partyts($chan) [unixtime]
		set ::partywho($chan) "-sBNC"
	}
	if {[string equal -nocase "join" $cmd]} {
		putclient ":$serv 005 $botnick CHANTYPES=[getisupport chantypes]~ :are supported by this server."
		if {[info exists partyban($chan,$client)]} {
			putclient ":$serv 484 $botnick $chan :Cannot join channel (You have been banned, repeated attempts to join will get you punished.)"
			sbnc:bcpartybutone $client ":-sBNC!user@$partyhost PRIVMSG $chan :User -$client attempted to join $chan, but is banned."
		} else {
			putclient ":$botname JOIN $chan"
			
			set newjoin 0
			if {[lsearch $chans $chan] == -1} {
				set newjoin 1
				lappend chans $chan
				setbncuser $client tag partyline [join $chans ","]
			}

			sbnc:partyline $client "NAMES $chan"
			sbnc:partyline $client "TOPIC $chan"

			if {[lindex $parameters 2] == 1 || $newjoin  == 1} {
				sbnc:bcpartybutone $client ":-$client!user@$partyhost JOIN $chan"

				if {[getbncuser $client admin] == 1} {
					putclient ":-sBNC!core@shroudbnc.org MODE $chan +o $botnick"
					sbnc:bcpartybutone $client ":-sBNC!core@shroudbnc.org MODE $chan +o -$client"
				} elseif {[getbncuser $client tag reseller] == 1} {
					putclient ":-sBNC!core@shroudbnc.org MODE $chan +v $botnick"
					sbnc:bcpartybutone $client ":-sBNC!core@shroudbnc.org MODE $chan +v -$client"
				}
			}
		}
	}

	if {[string equal -nocase "part" $cmd]} {
		if {[lsearch $partynopart $chan] == -1} {
			set idx [lsearch $chans $chan]

			if {$idx != -1} {
				setbncuser $client tag partyline [join [lreplace $chans $idx $idx] ","]

				putclient ":$botname PART $chan"
				sbnc:bcpartybutone $client ":-$client!user@$partyhost PART $chan :User Parted: [lrange $parameters 2 end]"
			}
		}
	}

	if {[string equal -nocase "names" $cmd]} {
		set idents "@-sBNC @Any-Abuse/Spam @Risks-Your-BNC"
		foreach user [bncuserlist] {
			if {[lsearch [split [string tolower [getbncuser $user tag partyline]] ","] $chan] != -1 && [getbncuser $user hasclient]} {
				if {[getbncuser $user admin] == 1} { 
					set acc "@"
				} elseif {[getbncuser $user tag reseller] == 1} {
					set acc "+"
				} else {
					set acc "" 
				}
				if {$client == $user} {
					lappend idents "$acc$botnick"
				} else {
					lappend idents "$acc\-$user"
				}
			}
		}

		putclient ":$serv 353 $botnick @ $chan :[join $idents]"
		putclient ":$serv 366 $botnick $chan :End of /NAMES list."
	}

	if {[string equal -nocase "mode" $cmd]} {
		if {[llength $parameters] < 3} {
			putclient ":$serv 324 $botnick $chan +nt"
			putclient ":$serv 329 $botnick $chan 0"
		} elseif {[lindex $parameters 2] == "+b"} {
			putclient ":$serv 368 $botnick $chan :End of Channel Ban List"
		} else {
			putclient ":$serv 482 $botnick $chan :You can't change modes on $chan"
		}
	}

	if {[string equal -nocase "topic" $cmd]} {
		if {[llength $parameters] < 3} {
			putclient ":$serv 332 $botnick $chan :$partytopic($chan)"
			putclient ":$serv 333 $botnick $chan $partywho($chan) $partyts($chan)"
		} else {
			set partytopic($chan) [lindex $parameters 2]
			set partyts($chan) [unixtime]
			set partywho($chan) "-$client"
			sbnc:bcparty ":-$client!user@$partyhost TOPIC $chan :$partytopic($chan)"
		}
	}

	if {[string equal -nocase "kick" $cmd]} {
		if {[llength $parameters] < 3} {
			putclient ":$serv 461 $botnick KICK :Not enough parameters"
		} elseif {[getbncuser $client admin] == 1} {
			partyline "[string trimleft [lindex $parameters 2] {-}] kick [lindex $parameters 1]"
		} else {
			putclient ":$serv 482 $botnick $chan :You can't kick users from $chan"
			if {[lsearch $partynopart $chan] == -1} {
				set idx [lsearch $chans [string tolower $chan]]
				if {$idx != -1} {
					setbncuser $client tag partyline [join [lreplace $chans $idx $idx] ","]
					putclient ":$botnick!user@$partyhost KICK $chan $botnick :You kicked yourself."
					sbnc:bcpartybutone $client ":-$client!noob@$partyhost KICK $chan -$client :I am noob, watch me kick myself."
				}
			} else {
				putclient ":$botnick!user@$partyhost KICK $chan $botnick :You kicked yourself."
				sbnc:bcpartybutone $client ":-$client!noob@$partyhost KICK $chan -$client :I am noob, watch me kick myself."
				sbnc:partyline $client "join $chan 1"
			}
		}
	}

	if {[string equal -nocase "privmsg" $cmd]} {
		if {[llength $parameters] < 3} {
			putclient ":$serv 461 $botnick PRIVMSG :Not enough parameters"
		} else {
			if {[lsearch [split [string tolower [getbncuser $client tag partyline]] ","] $chan] != -1} {
				sbnc:bcpartybutone $client ":-$client!user@$partyhost PRIVMSG $chan :[lindex $parameters 2]"
			} else {
				putclient ":$serv 404 $botnick $chan :Cannot send to channel"
			}
		}
	}
	if {[string equal -nocase "notice" $cmd]} {
		if {[llength $parameters] < 3} {
			putclient ":$serv 461 $botnick NOTICE :Not enough parameters"
		} else {
			if {[lsearch [split [string tolower [getbncuser $client tag partyline]] ","] $chan] != -1} {
				sbnc:bcpartybutone $client ":-$client!user@$partyhost NOTICE $chan :[lindex $parameters 2]"
			}
		}
	}
}

proc sbnc:privateparty {client parameters} {
	setctx $client

	global botnick botname server partyline partytopic partyts partywho partyhost

	if {![string match {-*} [lindex $parameters 1]]} {
		return
	}
	set cmd [lindex $parameters 0]
	if {[string tolower [lindex $parameters 1]] != {--}} {
		set nick [string tolower [string trimleft [lindex $parameters 1] {-}]]
		if {[string tolower $nick] == "sbnc"} { return }
	} else {
		set nick {--}
	}

	set serv [lindex [split $server ":"] 0]

	if {[string equal -nocase "privmsg" $cmd]} {
	haltoutput
		if {[llength $parameters] < 3} {
			putclient ":$serv 461 $botnick PRIVMSG :Not enough parameters"
		} else {
			if {$nick == {--}} {
				foreach user [bncuserlist] {
						setctx $user
						putclient ":-$client!user@$partyhost PRIVMSG $user :[lindex $parameters 2]"
				}
				setctx $client
			} elseif {[lsearch [string tolower [bncuserlist]] $nick] != -1} {
				sbnc:bcpartyone $client $nick ":-$client!user@$partyhost PRIVMSG $nick :[lindex $parameters 2]"
			} elseif {[string match #* $nick ] != 0} {
			set chan [string tolower [string trimleft [lindex $parameters 1] {-}]]
			set network [getisupport NETWORK]
				foreach x [bncuserlist] {
					   if { [getbncuser $x hasclient] } {
						set user_channel_list [split [string tolower [getbncuser $x channels]] {,}]
						setctx $x
						if {[lsearch $user_channel_list $chan] != -1 && [string match $network [getisupport NETWORK]] == 1} {
							putclient ":-$client!user@$partyhost PRIVMSG $chan :[lindex $parameters 2]"
						}
						setctx $client
					}
				}
			} else {
				putclient ":$serv 401 $botnick $nick :No such user on the BNC"
			}
		}
	}
	if {[string equal -nocase "notice" $cmd]} {
	haltoutput
		if {[llength $parameters] < 3} {
			putclient ":$serv 411 $botnick :Not enough parameters"
		} else {
			if {$nick == {--}} {
				foreach user [bncuserlist] {
						setctx $user
						putclient ":-$client!user@$partyhost NOTICE $user :[lindex $parameters 2]"
				}
				setctx $client
			} elseif {[lsearch [string tolower [bncuserlist]] $nick] != -1} {
				sbnc:bcpartyone $client $nick ":-$client!user@$partyhost NOTICE $nick :[lindex $parameters 2]"
			} elseif {[string match #* $nick ] != 0} {
			set chan [string tolower [string trimleft [lindex $parameters 1] {-}]]
			set network [getisupport NETWORK]
				foreach x [bncuserlist] {
					   if { [getbncuser $x hasclient] } {
						set user_channel_list [split [string tolower [getbncuser $x channels]] {,}]
						setctx $x
						if {[lsearch $user_channel_list $chan] != -1 && [string match $network [getisupport NETWORK]] == 1} {
							putclient ":-$client!user@$partyhost NOTICE $chan :[lindex $parameters 2]"
						}
						setctx $client
					}
				}
			} else {
				putclient ":$serv 401 $botnick $nick :No such user on the BNC"
			}
		}
	}
	if {[string equal -nocase "whois" $cmd]} {
	haltoutput
		if {[llength $parameters] < 2} {
			putclient ":$serv 431 $botnick :No nickname given"
		} else {
			if {[lsearch [string tolower [bncuserlist]] $nick] != -1} {
				putclient ":$serv 311 $botnick -$nick user $partyhost * :[getbncuser $nick realname]"
				putclient ":$serv 319 $botnick -$nick :[split [getbncuser $nick tag partyline] ,]"
				putclient ":$serv 312 $botnick -$nick $partyhost :KH BNC - Shroudbnc based goodness"
				if {![getbncuser $nick hasclient]} {
					putclient ":$serv 301 $botnick -$nick :Currently not connected to BNC"
				}
				if {[getbncuser $nick tag reseller] == "1"} {
					putclient ":$serv 310 $botnick -$nick :is a BNC Virtual Admin"
				}
				if {[getbncuser $nick admin] == 1} {
					putclient ":$serv 313 $botnick -$nick :is an IRC Operator - BNC Admin"
				}
				putclient ":$serv 307 $botnick -$nick :IRC nickname is [getbncuser $nick nick]"
				putclient ":$serv 318 $botnick -$nick :End of /WHOIS list."

			} else {
				putclient ":$serv 401 $botnick -$nick :No such user on the BNC"
			}
		}
	}
}



proc sbnc:bcparty {text} {
	set chan [lindex [split $text] 2]

	foreach user [bncuserlist] {
		set chans [split [string tolower [getbncuser $user tag partyline]] ","]

		if {[lsearch $chans $chan] != -1} {
			setctx $user
			putclient "$text"
		}
	}
}

proc sbnc:bcpartybutone {client text} {
	set chan [string tolower [lindex [split $text] 2]]
	set ctx [getctx]
	foreach user [bncuserlist] {
		set chans [split [string tolower [getbncuser $user tag partyline]] ","]

		if {[lsearch $chans $chan] != -1 && ![string equal -nocase $client $user]} {
			setctx $user
			putclient "$text"
		}
	}
	setctx $ctx
}

proc sbnc:bcpartyone {client nick text} {
	setctx $nick
	putclient "$text"
	setctx $client
}

proc sbnc:partyattach {client} {
	global botnick botname partyline server partyhost
	set chans [split [string tolower [getbncuser $client tag partyline]] ","]
	setctx $client
	putclient ":[lindex [split $server ":"] 0] 005 $botnick CHANTYPES=[getisupport chantypes]~ :are supported by this server."
	foreach chan $partyline {
		if {[lsearch $chans [string tolower $chan]] != -1} {
			sbnc:partyline $client "join $chan 1"
		}
	}
}

proc sbnc:partydetach {client} {
	global partyline partyhost
	set chans [split [string tolower [getbncuser $client tag partyline]] ","]
	foreach chan $partyline {
		if {[lsearch $chans [string tolower $chan]] != -1} {
			sbnc:bcpartybutone $client ":-$client!user@$partyhost PART $chan :Disconnected from BNC"
		}
	}
}

proc sbnc:partysync {client} {
	global partyline partyhost

	set chans [split [string tolower [getbncuser $client tag partyline]] ","]

	foreach chan $partyline {
		if {[lsearch $chans [string tolower $chan]] != -1} {

			sbnc:bcpartybutone $client ":-$client!user@$partyhost PART $chan :Removing user"
		}
	}
}

proc sbnc:versionfix {client} {
global server botnick botname
	set serv [lindex [split $server ":"] 0]
	utimer 2 "setctx $client; putclient \":$serv 005 $botnick CHANTYPES=[getisupport chantypes]~ :are supported by this server.\""
	utimer 10 "setctx $client; putclient \":$serv 005 $botnick CHANTYPES=[getisupport chantypes]~ :are supported by this server.\""
}
