# NETSPLIT 7 - This script does it's best to suppress the excessive 
# joins and signoffs due ONLY to netsplits.  It should pass regular
# signoffs.   Need at least ircII2.2pre6
# Version II  handles multiple channels. 
# Version III ignores bogus signoff messages
# Version IV  handles multiple splits.
# Version V   handles multiple splits and ignores bogus signoff messages. also
#             adds timestamps to split/join messages
# Version VI  For ircII2.2pre8 and beyond. Uses encode() and decode() 
# Version VII Fixed a problem with encode() and decode() and case
#             sensitive channel names, + adding lformat()
#
# This one by Daemon
# CONVERTED for ircII2.2pre8
# Version V by poxaV (cgw@unt.edu), from Daemon's code
# modified last 7-03-93

#shows the current time in HH:MM:SS format
alias currtime @ function_return = strftime(%T)

# This function tests for bogus splits.
alias isbogus {
	if ([$3]) { @ function_return = 1 }
	if (rmatch(.$1. $isbogus.pats *..*)) { @ function_return = 1 }
	if (rmatch(.$2. $isbogus.pats *..*)) { @ function_return = 1 }
}

# Add patterns.. like /boguspat *bonk* *thud* *haha*
# that will NOT be treated as server names..
alias boguspat ^assign isbogus.pats $isbogus.pats $0-;echo $0- added

# Next two are pretty obvious
alias boguslist echo Pats: $isbogus.pats
alias bogusclear ^assign -isbogus.pats;echo Bogus list clean

# If first word in Signoff contains a period then assume servername
# and thus a a split.  Stash in assoc array.
ON ^CHANNEL_SIGNOFF "% % %.% %.%" {
	if (isbogus($1-)) 
		{ echo *** Quit: $1 \($0, $2-\) }
		{ ^netbroke $encode($tolower($0)) $encode($1) $encode($2).$encode($3) $2 $3 }
}

# Stuff array. Tell us what server broke and set split flag.
^alias netbroke {
	@ signcross[$2][$0][$1] = 1
	@ signoffs[$0][$1] = [$2]
	@ splittime[$2] = time()
	if ( !isbroke[$2] )
	{
		xecho -level OPNOTES *** Netsplit at $currtime() \($3-\)
		@ isbroke[$2] = 1
		@ splitname[$2] = [$3-]
	}
}

# When a person joins a channel.. Check them against the array.
# If they are in array, then remove silently.  Otherwards echo normally
ON #^JOIN -10 * {
	^netjoined $encode($tolower($1)) $encode($0) $1 $0 $USERHOST()
}

# Unset the split flag
alias netjoined {
	if ( signoffs[$0][$1] )
	{
		if ( isbroke[$signoffs[$0][$1]] )
		{
			xecho -level OPNOTES *** Netjoined at $currtime() \($splitname[$signoffs[$0][$1]]\)
		}
		^assign -isbroke[$signoffs[$0][$1]]
		^assign -signcross[$signoffs[$0][$1]][$0][$1]
		^assign -signoffs[$0][$1]
		@ rejoin = 1
	}
}

# Clear the array every 10 minutes to prevent excess garbage
on #^timer 70 * netclean

alias netclean {
	foreach splittime ii
	{
		foreach splittime.$ii jj
		{
			if ( time() - splittime[$ii][$jj] > 300 )
			{
				foreach signcross.$(ii).$jj xx
				{
					foreach signcross.$(ii).$(jj).$xx yy
					{
						^assign -signcross[$ii][$jj][$xx][$yy]
						^assign -signoffs[$xx][$yy]
					}
				}
				^assign -xx
				^assign -yy
				^assign -isbroke[$ii][$jj]
				^assign -splitname[$ii][$jj]
				^assign -splittime[$ii][$jj]
			}
		}
	}
	^assign -ii
	^assign -jj
}

alias netpurge {
	purge isbroke
	purge splitname
	purge splittime
	purge signcross
	purge signoffs
}

# If you want to suppress mode changes by servers.. (usually after a split)
# then uncomment next line
# ^on ^mode "%.%" #

# If you want to look an array.. Type /show <arrayname>
# Lists keys and contents
alias showsplit {
	if ([$($0)]) {echo $0 $($0)}
	foreach $0 ii
	{
		showsplit $0.$ii
	}
}

alias purge {
	foreach $0 ii
	{
		purge $0.$ii
	}
	^assign -ii
	^assign -$0
}

alias wholeft {
	foreach signoffs ii
	{
		foreach signoffs.$ii jj
		{
			echo $lformat(15 $decode($ii)) $lformat(10 $decode($jj)) $splitname[$signoffs[$ii][$jj]]
		}
	}
	^assign -ii
	^assign -jj
}

# format and lformat differ from $[-num]var and $[num]var in that
# They don't chop off the string if it is too long.

alias lformat {
	@ IRCII.word = [$1-]
	if (@IRCII.word < [$0]) 
		{ @ function_return = [$([$0]IRCII.word)] } 
		{ @ function_return = [$IRCII.word] } 
}
