#!/usr/bin/perl 
use Net::IRC;
use POSIX qw(strftime);
use utf8;

# [ ----------------------------------------------------- ]
#                                too many secret channels
# [ kpsbr ----------------------------------------------- ]

# bsd license..

my %DEF;
our @CHANS  = ();

#
# !!! ADJUST THESE SETTINGS: !!!
# 
$DEF{WORDLIST}		= "/usr/share/dict/words";
$DEF{NICK} 		= 'setec_';
$DEF{SERVER} 		= 'irc.efnet.eu'; 
$DEF{PORT}		= 6666;
$DEF{CHAN}		= "#h4x0rZZZ"; # chan is optional, just remove line if you don't want live feedback via irc
$DEF{CURLINE}		= 1; # start at line x of wordlist ; bot will end at a blank line(!), so _START AT 1 IF FIRST LINE IS BLANK!!_
$DEF{WRITELOG}		= 1; # either write log or write to stderr

# you can leave these alone if you dare:
$DEF{IRCNAME} 		= 'Yous Uck';
$DEF{USER} 		= 'toor';
$DEF{DELAY} 		= 4;	
$DEF{SIGNOFFPHRASE} = "hello. quit, pls"; # if CHAN is defined and someone says these words, bot will instantly quit
$DEF{DEBUG}		= 0; # 1=give LOTS of debug feedback to stderr

# no changes necessary from this point on

# ---------------------------------------------------------

my $irc = new Net::IRC;
my $CONNECTED = 0;
my $SECRETCHANS = 0;

&log("Creating connection to IRC server...\n");

my $conn = $irc->newconn( 
			 Server   => ($ARGV[0]  || $DEF{SERVER}),
			 Port     => $DEF{PORT},
			 Nick     => $DEF{NICK},
			 Ircname  => $DEF{IRCNAME},
			 Username => $DEF{USER})
    or die "can't connect to IRC server $DEF{SERVER} on port $DEF{PORT}.\n";

# ----------------------------------------------------------------------
sub log 
{
	my $str = shift;
	my $donotannounce = shift;
	$conn->privmsg($DEF{CHAN},$str) if !$donotannounce && $conn && $DEF{CHAN};
	my $logfilename = $DEF{NICK} . '-' . strftime("%Y-%m-%d", localtime) . '.log';
	my $time = strftime "%H:%M ", localtime;
	my $logline = $time . $str . "\n";	
	print STDERR $logline && return unless $DEF{WRITELOG};

	&debug("log: $str");
	open LOGFILE, ">>$logfilename";
	print LOGFILE $logline;
	close LOGFILE;
}

sub debug 
{
	my $str = shift;
	return unless $DEF{DEBUG};
	my $time = strftime "%Y-%m-%d %H:%M", localtime;
	print STDERR "$time [DEBUG] $str\n";
}

sub on_connect 
{
	my ($self, $event) = @_;
	if($DEF{CHAN}) 
	{
		$self->join($DEF{CHAN});
		&log("(joined ".$DEF{CHAN}.")");
	}	
	$CONNECTED = 1;
}

sub on_msg
{
   	my ($self, $event) = @_;
   	my ($nick) = $event->nick;
   	my ($arg) = ($event->args);
	&log("*$nick* ". $arg);
}

sub on_public 
{
   	my ($self, $event) = @_;
    my ($nick, $mynick) = ($event->nick, $self->nick);
    my ($arg) = ($event->args);
    my ($channel) = ($event->to)[0];

   	&log("$channel <$nick> $arg", 1);
    
   	if ($arg =~ /$DEF{SIGNOFFPHRASE}/i) {
		&log("(".$event->nick . 'said magic words for me to sign off.)');
		$self->quit();
		exit 0;
   	}
}

sub get_next_chan
{
	$cmd = "tail -n +".(++$DEF{CURLINE})." $DEF{WORDLIST} | head -n 1";
	my $word = `$cmd`;
	chomp($word);
	return "" unless $word;
	$word =~ s/[\s\0\r\n,\a]//g;

	"#".$word;
}

sub on_mode 
{
	my ($self, $event) = @_;
	my @to = $event->to;
	my ($nick, $mynick) = ($event->nick, $self->nick);
	my @args = ($event->args);

	&debug("found channel $args[1] mode $args[2]");
	&log("found secret chan ".++$SECRETCHANS.": $args[1] w/ mode $args[2]") if $args[2] =~ /s/ && $args[2] !~ /^-/;
}

# --------------------------------- main ---

$conn->add_handler('public', \&on_public);
$conn->add_handler('msg',    \&on_msg);
$conn->add_handler(324, \&on_mode);
$conn->add_global_handler('disconnect', \&on_disconnect);
$conn->add_global_handler(376, \&on_connect);

&debug("debug system works flawlessly if you can read this line :)");

while (1) 
{
	if($CONNECTED) 
	{
		my $chan = &get_next_chan();
		if($chan) 
		{
			debug("next chan will be: $chan");
			$conn->mode($chan, "");
			sleep($DEF{DELAY}) unless $DEF{CURLINE} % 23;
		} else {
			debug("loop for some time until probably all on_mode() events that will eventually arrive have probably been triggered");
			for($i=0;$i<1000;$i++) {
				$irc->do_one_loop();
			}
			&log("found $SECRETCHANS secret chans. no more words in list. goodbye.");
			exit 0;
		}
	}
    $irc->do_one_loop();
}

# end of file

