Language: EN FR PT ES NL DE SV RU
#################################################
# clink.tcl Channel Linker v1.2
# Written by {SImPhAt}, May 6th 2002
#
# This script lets you link channels (as many as you
# like) on different (or same) IRC Networks using 2 or
# more eggdrops.
#
# Messages are sent in a botnet-link connection.
#
# Easy to configure.
#
# Join, Part, Nick change, Quit, Kick, Msgs and 
# Actions (/me) are currently relayed.
#
# Tested on eggdrop v1.6.x (3 bots) relaying between 3
# different channels.
#
# E-mail questions or comments to simon.boulet@divahost.net.
# I'd like to know who is using my script and where, just to
# see it live in action =).
#
# Changes since 1.0:
#	1) Linking of channels that do not have the same name
#	   (ex: linking #help with #help.quebec-chat)
#	2) Spelling correction in "nick as joined #chan" should be has
#	3) Stupid bug showing empty () on kick/part/quit with no reason
#	4) Tested everything with 3 channels/networks/bots.
#
# TODO:
#	1) Flood protection.
#	2) List current nicks on the linked side (.names).
#	3) Remote topic change, kick/ban, op.
#
#################################################
# Configuration
#################################################
#
# Note: I was relaying #clink.qc(Quebec-Chat) #clink.io(Ionical) and
# #clink.un(Undernet) all together (those 3 eggdrops where using the
# same .tcl source).
#
# CLink-QC on Quebec-Chat, CLink-IO on Ionical and CLink-UN on Undernet.
#
# Nickname (botnet-nick) of the bots who are involved in the relaying.
# Enter all of them, case-sensitive.
#
set clink_botnicks {"gs-0" "qnet-0"}
#
# The channel(s) you want to relay messages from and the bot that is on.
#
# You need to "set network 'Network-Name'" in your bot(s) .conf file.
# If you don't want to waste time searching what you put there, simply
# .rehash your bot with clink.tcl loaded and you should see something like:
#
# clink.tcl: I am CLink-UN running on Undernet.
# --- Network-Name -------------------^^^^^^^^
# Loaded clink.tcl: {SImPhAt} Channel Linker v1.x
#
# Case-sensitive.
#
# Syntax: set clink_onchan(#chan@network) "bot-name"
set clink_onchan(#pugbot@GameSurge) "gs-0"
set clink_onchan(#pugbot@QuakeNet) "qnet-0"
 
set clink_onchan(#pugbot.ctf@GameSurge) "gs-0"
set clink_onchan(#pugbot.ctf@QuakeNet) "qnet-0"
 
set clink_onchan(#pugbot.eu@GameSurge) "gs-0"
set clink_onchan(#pugbot.eu@QuakeNet) "qnet-0"
 
set clink_onchan(#pugbot.eu.ts@GameSurge) "gs-0"
set clink_onchan(#pugbot.eu.ts@QuakeNet) "qnet-0"
 
set clink_onchan(#pugbot.au@GameSurge) "gs-0"
set clink_onchan(#pugbot.au@QuakeNet) "qnet-0"
 
set clink_onchan(#pugbot.sa@GameSurge) "gs-0"
set clink_onchan(#pugbot.sa@QuakeNet) "qnet-0"
 
set clink_onchan(#pugbot.chat@GameSurge) "gs-0"
set clink_onchan(#pugbot.chat@QuakeNet) "qnet-0"
 
set clink_onchan(#urtdevs@GameSurge) "gs-0"
set clink_onchan(#urtdevs@QuakeNet) "qnet-0"
 
#
# The channel(s) where you want the messages to be relayed.
#
# For each channels you need to tell where you want everything
# to be sent to.
#
# Case-sensitive.
#
# Syntax: set clink_relayto(#from_chan@network1) {"#destination_chan@network2"}
set clink_relayto(#pugbot@GameSurge) {"#pugbot@QuakeNet"}
set clink_relayto(#pugbot@QuakeNet) {"#pugbot@GameSurge"}
 
set clink_relayto(#pugbot.ctf@GameSurge) {"#pugbot.ctf@QuakeNet"}
set clink_relayto(#pugbot.ctf@QuakeNet) {"#pugbot.ctf@GameSurge"}
 
set clink_relayto(#pugbot.au@GameSurge) {"#pugbot.au@QuakeNet"}
set clink_relayto(#pugbot.au@QuakeNet) {"#pugbot.au@GameSurge"}
 
set clink_relayto(#pugbot-priv@GameSurge) {"#pugbot.debug@rizon"}
set clink_relayto(#pugbot.debug@rizon) {"#pugbot-priv@GameSurge"}
 
set clink_relayto(#pugbot.eu@GameSurge) {"#pugbot.eu@QuakeNet"}
set clink_relayto(#pugbot.eu@QuakeNet) {"#pugbot.eu@GameSurge"}
 
set clink_relayto(#pugbot.sa@GameSurge) {"#pugbot.sa@QuakeNet"}
set clink_relayto(#pugbot.sa@QuakeNet) {"#pugbot.sa@GameSurge"}
 
set clink_relayto(#pugbot.eu.ts@GameSurge) {"#pugbot.eu.ts@QuakeNet"}
set clink_relayto(#pugbot.eu.ts@QuakeNet) {"#pugbot.eu.ts@GameSurge"}
 
set clink_relayto(#pugbot.chat@GameSurge) {"#pugbot.chat@QuakeNet"}
set clink_relayto(#pugbot.chat@QuakeNet) {"#pugbot.chat@GameSurge"}
 
set clink_relayto(#pugbot.invite@GameSurge) {"#pugbot.invite@QuakeNet"}
set clink_relayto(#pugbot.invite@QuakeNet) {"#pugbot.invite@GameSurge"}
 
set clink_relayto(#urtdevs@GameSurge) {"#urtdevs@QuakeNet"}
set clink_relayto(#urtdevs@QuakeNet) {"#urtdevs@GameSurge"}
 
set eu_chans {"#pugbot.eu@QuakeNet" "#pugbot.eu@GameSurge"}
set euts_chans {"#pugbot.eu.ts@QuakeNet" "#pugbot.eu.ts@GameSurge"}
set sa_chans {"#pugbot.sa@QuakeNet" "#pugbot.sa@GameSurge"}
set au_chans {"#pugbot.au@QuakeNet" "#pugbot.au@GameSurge"}
 
#
# Should we add colors to join, part, nick, quit,
# action, etc.
#
set clink_usecolor 1
#
# Do you want me to display the network name?
#
set clink_relaynet 0
#
# Characters to use when displaying the nicknames in channels msgs.
#
# Exemples:
# <Nickname> hello
# set clink_charmsgs {"<" ">"}
#
# (Nickname) hello
set clink_charmsgs {"" "\003:"}
#
# Nicks to be ignored
set ignorelist {"GT-PUGBot" "GT-GSN" "GT-ETG" "GT-QuN" "GT-1" "GT-2" "GT-3" "GT-4" "GT-5" "GT-6" "GT-7" "GT-8" "GT-9" "GT-10" "GT-Backup" "ChanServ" "Q" "TheCheatBot"}
#
#################################################
# Script, you should *not* need to change
# anything below.
#################################################
bind pubm - * clink_chanpubm
bind pub * .eu clink_chanpubm_eu
bind pub * .eu.ts clink_chanpubm_euts
bind pub * .au clink_chanpubm_au
bind pub * .sa clink_chanpubm_sa
#bind nick - * clink_channick
#bind sign - * clink_chanquit
#bind kick - * clink_chankick
#bind join - * clink_chanjoin
#bind part - * clink_chanpart
bind ctcp - "ACTION" clink_chanacti 
bind bot - clink clink_botdat
source ./scripts/gt-nickcol.tcl
 
# Colors settings (Default: mIRC style)
if {$clink_usecolor == 1} {
	set clink_color(pubm) ""
	set clink_color(nick) "\0033"
	set clink_color(quit) "\0032"
	set clink_color(kick) "\0033"
	set clink_color(join) "\0033"
	set clink_color(part) "\0033"
	set clink_color(acti) "\0036"
} else {
        set clink_color(pubm) ""
        set clink_color(nick) ""
        set clink_color(quit) ""
        set clink_color(kick) ""
        set clink_color(join) ""
        set clink_color(part) ""
        set clink_color(acti) ""
}
# Done
 
# Check current configuration
if {${botnet-nick} == ""} {
	set {botnet-nick} $nick
	putlog "clink.tcl: Warning: botnet-nick not defined in .conf file, using \"$nick\"."
}
 
if {[lsearch $clink_botnicks ${botnet-nick}] == -1} {
	die "clink.tcl: Fatal: Bot \"${botnet-nick}\" not defined in clink_botnicks. Please edit clink.tcl and check your configuration."
}
 
if {$network == "unknown-net"} {
	putlog "clink.tcl: Warning: network not defined in .conf file, using \"unknown-net\"."
}
# Done
 
proc clink_chanpubm_eu {nick uhost hand chan text} {
	global clink_onchan network {botnet-nick} ignorelist
	set chan "#pugbot.eu"
	if {${botnet-nick} == "qnet-0"} {
		set faux_net_nick "qnet-0"
		set faux_network "QuakeNet"
		set real_nick "gs-0"
		set real_network "GameSurge"
	} elseif {${botnet-nick} == "gs-0"} {
		set faux_net_nick "gs-0"
		set faux_network "GameSurge"
		set real_nick "qnet-0"
		set real_network "QuakeNet"
	} else {
		putlog "clink.tcl: Warning: bot $clink_onchan($clink_relaychan) not linked. ${botnet-nick} $clink_onchan($clink_relaychan)"
	}
 
	putbot "$real_nick" [concat "clink $chan $faux_network" "pubm" [clink_cleannick $nick] $text]
	putbot "$real_nick" [concat "clink #pugbot.chat $faux_network" "pubm" [clink_cleannick $nick] $text]
	clink_botdat "$real_nick" "clink" [concat "$chan $real_network" "pubm" [clink_cleannick $nick] $text]
 
 
}
 
proc clink_chanpubm_euts {nick uhost hand chan text} {
	global clink_onchan network {botnet-nick} ignorelist
	set chan "#pugbot.eu.ts"
	if {${botnet-nick} == "qnet-0"} {
		set faux_net_nick "qnet-0"
		set faux_network "QuakeNet"
		set real_nick "gs-0"
		set real_network "GameSurge"
	} elseif {${botnet-nick} == "gs-0"} {
		set faux_net_nick "gs-0"
		set faux_network "GameSurge"
		set real_nick "qnet-0"
		set real_network "QuakeNet"
	} else {
		putlog "clink.tcl: Warning: bot $clink_onchan($clink_relaychan) not linked. ${botnet-nick} $clink_onchan($clink_relaychan)"
	}
 
	putbot "$real_nick" [concat "clink $chan $faux_network" "pubm" [clink_cleannick $nick] $text]
	putbot "$real_nick" [concat "clink #pugbot.chat $faux_network" "pubm" [clink_cleannick $nick] $text]
	clink_botdat "$real_nick" "clink" [concat "$chan $real_network" "pubm" [clink_cleannick $nick] $text]
 
 
}
proc clink_chanpubm_au {nick uhost hand chan text} {
	global clink_onchan network {botnet-nick} ignorelist
	set chan "#pugbot.au"
	if {${botnet-nick} == "qnet-0"} {
		set faux_net_nick "qnet-0"
		set faux_network "QuakeNet"
		set real_nick "gs-0"
		set real_network "GameSurge"
	} elseif {${botnet-nick} == "gs-0"} {
		set faux_net_nick "gs-0"
		set faux_network "GameSurge"
		set real_nick "qnet-0"
		set real_network "QuakeNet"
	} else {
		putlog "clink.tcl: Warning: bot $clink_onchan($clink_relaychan) not linked. ${botnet-nick} $clink_onchan($clink_relaychan)"
	}
 
	putbot "$real_nick" [concat "clink $chan $faux_network" "pubm" [clink_cleannick $nick] $text]
	putbot "$real_nick" [concat "clink #pugbot.chat $faux_network" "pubm" [clink_cleannick $nick] $text]
	clink_botdat "$real_nick" "clink" [concat "$chan $real_network" "pubm" [clink_cleannick $nick] $text]
 
 
}
 
proc clink_chanpubm_sa {nick uhost hand chan text} {
	global clink_onchan network {botnet-nick} ignorelist
	set chan "#pugbot.sa"
	if {${botnet-nick} == "qnet-0"} {
		set faux_net_nick "qnet-0"
		set faux_network "QuakeNet"
		set real_nick "gs-0"
		set real_network "GameSurge"
	} elseif {${botnet-nick} == "gs-0"} {
		set faux_net_nick "gs-0"
		set faux_network "GameSurge"
		set real_nick "qnet-0"
		set real_network "QuakeNet"
	} else {
		putlog "clink.tcl: Warning: bot $clink_onchan($clink_relaychan) not linked. ${botnet-nick} $clink_onchan($clink_relaychan)"
	}
 
	putbot "$real_nick" [concat "clink $chan $faux_network" "pubm" [clink_cleannick $nick] $text]
	putbot "$real_nick" [concat "clink #pugbot.chat $faux_network" "pubm" [clink_cleannick $nick] $text]
	clink_botdat "$real_nick" "clink" [concat "$chan $real_network" "pubm" [clink_cleannick $nick] $text]
 
 
}
 
proc clink_botsend {chan param} {
	global clink_onchan {botnet-nick} network clink_relayto
	foreach clink_relaychan $clink_relayto($chan@$network) {
		set send_chan [lindex [split $clink_relaychan "@"] 0]
		if {[lsearch -exact [bots] $clink_onchan($clink_relaychan)] == -1} {
			if {$clink_onchan($clink_relaychan) == ${botnet-nick}} {
				if {${botnet-nick} == "gs-0"} {
					set faux_net_nick "qnet-0"
					set faux_network "QuakeNet"
				} elseif {${botnet-nick} == "qnet-0"} {
					set faux_net_nick "gs-0"
					set faux_network "GameSurge"
				} else {
					putlog "clink.tcl: Warning: bot $clink_onchan($clink_relaychan) not linked. ${botnet-nick} $clink_onchan($clink_relaychan)"
				}
				clink_botdat "$faux_net_nick" "clink" "$send_chan $faux_network $param"
			} else {
				putlog "clink.tcl: Warning: bot $clink_onchan($clink_relaychan) not linked. ${botnet-nick} $clink_onchan($clink_relaychan)"
			}
		} else {
			#putlog "I send you!"
			#putlog "$clink_onchan($clink_relaychan) clink $send_chan $network $param"
			putbot $clink_onchan($clink_relaychan) "clink $send_chan $network $param"
		}
	}
}
 
proc clink_chanpubm {nick uhost hand chan text} {
	global clink_onchan network {botnet-nick} ignorelist
	#putlog "I see you!"
	if {[info exist clink_onchan($chan@$network)]} {
		set qcommand [lsearch $text .* ]
		foreach toignore $ignorelist {
			if {$qcommand != "0" } {
				if {[clink_cleannick $nick] == $toignore} {
					set qcommand "0"
				}
			}
		}
		if {$qcommand != "0" } {
			set qcommand [lsearch $text !* ]
		}
		if {$qcommand != "0" } {
			set qcommand [lsearch $text ,* ]
		}
		if {$qcommand != "0" } {
			if {${botnet-nick} != $clink_onchan($chan@$network)} {
				set qcommand "0"
			}
		}
		if {$qcommand != "0" } {
			#putlog "$chan [concat pubm [clink_cleannick $nick] $text]"
			clink_botsend $chan [concat "pubm" [clink_cleannick $nick] $text]
		}
	}
}
 
proc clink_channick {nick uhost hand chan newnick} {
        global clink_onchan network
        if {[info exist clink_onchan($chan@network)]} {
		clink_botsend $chan [concat "nick" [clink_cleannick $nick] [clink_cleannick $newnick]]
	}
}
 
proc clink_chanquit {nick uhost hand chan reason} {
        global clink_onchan network
        if {[info exist clink_onchan($chan@$network)]} {
		clink_botsend $chan [concat "quit" [clink_cleannick $nick] $uhost $reason]
	}
}
 
proc clink_chankick {nick uhost hand chan knick reason} {
	global clink_onchan network
	if {[info exist clink_onchan($chan@$network)]} {
		clink_botsend $chan [concat "kick" [clink_cleannick $nick] [clink_cleannick $knick] $reason]
	}
}
 
proc clink_chanjoin {nick uhost hand chan} {
        global clink_onchan network
        if {[info exist clink_onchan($chan@$network)]} {
		clink_botsend $chan [concat "join" [clink_cleannick $nick] $uhost]
	}
}
 
proc clink_chanpart {nick uhost hand chan reason} {
        global clink_onchan network
        if {[info exist clink_onchan($chan@$network)]} {
		clink_botsend $chan [concat "part" [clink_cleannick $nick] $uhost $reason]
	}
}
 
proc clink_chanacti {nick uhost hand chan action text} {
        global clink_onchan network {botnet-nick}
	if {[info exist clink_onchan($chan@$network)]} {
		set qcommand "-1"
		if {$qcommand != "0" } {
			if {${botnet-nick} != $clink_onchan($chan@$network)} {
				set qcommand "0"
			}
		}
		if {$qcommand != "0" } {
			clink_botsend $chan [concat "acti" [clink_cleannick $nick] $action $text]
		}
	}
}
 
proc clink_botdat {bot clink param} {
	global relayname clink_relaynet clink_color clink_charmsgs clink_relayto network
	#putlog "I receive you!"
	if {$clink_relaynet == 1} {
		set clink_network "\[[lindex $param 1]\] "
	} else {
		set clink_network ""
	}
	if {[lrange $param 5 end] != ""} {
		set reason "\([lrange $param 5 end]\)"
	} else {
		set reason ""
	}
	#putlog "I am here!"
	#putlog "$relayname [lindex $param 1]"
	if {$relayname == [lindex $param 1]} {
		set nickcolor [colornick [join [lindex $param 3]]]
		set clink_destchan [lindex [split [lindex $clink_relayto([lindex $param 0]@[lindex $param 1]) [lsearch -glob $clink_relayto([lindex $param 0]@[lindex $param 1]) "*@$network"]] @] 0]
		#putlog "I am here also!"
		switch [lindex $param 2] {
			pubm	{ putserv "PRIVMSG $clink_destchan :$clink_network$nickcolor[lindex $clink_charmsgs 0][join [lindex $param 3]][lindex $clink_charmsgs 1] [join [lrange $param 4 end]]" }
			nick	{ putserv "PRIVMSG $clink_destchan :$clink_network$clink_color(nick)*** [lindex $param 3] is now known as [lindex $param 4]" }
			quit	{ putserv "PRIVMSG $clink_destchan :$clink_network$clink_color(quit)*** [lindex $param 3] \([lindex $param 4]\) Quit $reason" }
			kick	{ putserv "PRIVMSG $clink_destchan :$clink_network$clink_color(kick)*** [lindex $param 4] was kicked by [lindex $param 3] $reason" }
			join	{ putserv "PRIVMSG $clink_destchan :$clink_network$clink_color(join)*** [lindex $param 3] \([lindex $param 4]\) has joined [lindex $param 0]" }
			part	{ putserv "PRIVMSG $clink_destchan :$clink_network$clink_color(part)*** [lindex $param 3] \([lindex $param 4]\) has left [lindex $param 0] $reason" }
			acti	{ putserv "PRIVMSG $clink_destchan :$clink_network$clink_color(acti)* [lindex $param 3] [join [lrange $param 5 end]]" }
			default { putlog "clink.tcl: Warning: unknown action type \"[lindex $param 2]\" for [lindex $param 0]." }
		}
	}
}
proc clink_cleannick {nick} {
	if {[string range $nick 0 0] == "\{"} {
		set nick "\\$nick"
	}
        return $nick
}
putlog "clink.tcl: I am ${botnet-nick} running on $network."
putlog "Loaded clink.tcl: {SImPhAt} Channel Linker v1.2"