Revision 1 (by moose, 2006/07/20 11:34:56) initial import
#!/usr/bin/perl

use warnings;
use strict;
our %_SIG;
our %_SIG_SUB;

use IRC;
use IRC::Config;
use IRC::Connection::Server;
use IRC::Connection::Console;
use IRC::User;
use IRC::Event;
use IRC::Channel;
use IO::Multiplex;

IRC->set_logfh(\*STDERR);

our @join = ('#tomasu'); #, '#foo', '#bar', '#foobar');

our %trig = (
	'!start' => \&do_start,
	'!stop' => \&do_stop,
	'!move' => \&do_move,
	'!join' => \&do_join,
	'!addai' => \&do_addai,
);

our $conf = new IRC::Config( file => 'tictactoe.cfg' );
our $mux = new IO::Multiplex;
our $user = new IRC::User(nick => 'MoosieD', altnick => 'M??sie', realname => 'just a bot');

$mux->add(\*STDIN);
$mux->set_callback_object(__PACKAGE__, \*STDIN);

our $server = new IRC::Connection::Server(
	'mux' => $mux,
	'address' => 'chat.freenode.net',
	'port' => '6667',
	'user' => $user,
	'conf' => $conf
);

our $console = new IRC::Connection::Console(
	'mux' => $mux,
	'port' => '3333',
	'conf' => $conf
);

#$console->connect();

$server->register_event('CONNECT', sub { my $self = shift; $self->log("EVENT CONNECT: ".$self->address.":".$self->port); });
$server->register_event('DISCONNECT', sub { my $self = shift; $self->log("EVENT DISCONNECT: ".$self->address.":".$self->port); });
$server->register_event('422', \&do_join);
$server->register_event('376', \&do_join);

$server->register_event('PRIVMSG', \&privmsg);

$server->register_event('CONNECT FAILED', sub { my $self = shift; $self->log("EVENT CONNECT FAILED: ".$self->address.":".$self->port); });
$server->register_event($IRC::Event::ERR::ERRONEUSNICKNAME, sub { shift->log("EVENT $_[0] ERRONEUS NICK NAME"); });
$server->register_event($IRC::Event::ERR::NICKNAMEINUSE, sub { shift->log("EVENT $_[0] NICK NAME IN USE"); });
$server->register_event($IRC::Event::ERR::NICKCOLLISION, sub { shift->log("EVENT $_[0] NICK COLLISION"); });
$server->connect();

register_sig(
	PIPE => sub { $server->log("SIG$_[0] received"); },
	INT  => sub { $server->log("SIG$_[0] received"); $console->disconnect('SIGINT');  $server->disconnect('SIGINT'); $mux->remove(\*STDIN); },
	TERM => sub { $server->log("SIG$_[0] received"); $console->disconnect('SIGTERM'); $server->disconnect('SIGTERM'); $mux->remove(\*STDIN); },
	QUIT => sub { $server->log("SIG$_[0] received"); $console->disconnect('SIGQUIT'); $server->disconnect('SIGQUIT'); $mux->remove(\*STDIN); },
#	HUP  => sub { $self->sig_hup() },
#	CHLD => sub { $self->sig_chld() },
);

$mux->set_timeout(\*STDIN, 1);
$mux->loop;

sub do_start;
sub do_stop;
sub do_move;
sub do_join;
sub do_addai;

sub do_join {
	my $self = shift;
	for (@join) { $self->join($_); }
}

sub mux_timeout {
	my $self = shift;
	my $mux = shift;
	my $fh = shift;

	if($fh == \*STDIN) {
		for(keys %_SIG) {
			if($_SIG{$_} == 1) {
				$_SIG_SUB{$_}->($_);
				$_SIG{$_} = 0;
			}
		}

		$mux->set_timeout(\*STDIN, 1);
	}
}

sub mux_input {
	my $self  = shift;
	my $mux   = shift;
	my $fh    = shift;
	my $input = shift;
	my @lines = split "\n", $$input;

	for(@lines) {
		if(/^join\s+(#[^\s]+)/) {
			$::server->join($1);
		}
	}

	print $fh $$input;

	# Remove the input from the input buffer.
	$$input = '';
}

sub mux_close {
	my $self = shift;
	$self->trigger_event('DISCONNECTED');
	$self->log("Connection Closed");
}

sub register_sig {
  die 'Usage: register_sig( SIGNAME => \&code_ref )' if @_ % 2;
  if( @_ > 2 ){
    register_sig(shift(),shift()) while @_;
    return;
  }
  my $sig      = shift;
  my $code_ref = shift;
  my $ref = ref($code_ref);

  if( ! $ref ){
    if( $code_ref eq 'DEFAULT' ){
      delete $_SIG{$sig};
      delete $_SIG_SUB{$sig};
      $SIG{$sig} = 'DEFAULT';
    }elsif( $code_ref eq 'IGNORE' ){
      delete $_SIG{$sig};
      delete $_SIG_SUB{$sig};
      $SIG{$sig} = 'IGNORE';
    }else{
      die "Scalar argument limited to \"DEFAULT\" and \"IGNORE\".";
    }

  }elsif( $ref eq 'CODE' ){

    $_SIG{$sig} = 0;
    $_SIG_SUB{$sig} = $code_ref;
    $SIG{$sig} = sub{ $_SIG{$_[0]} = 1; };

  }else{

    die "Unsupported sig type -- must be 'DEFAULT' or a code ref.";
  }
}

#package IRC::Bot::TicTacToe;
#use base IRC::Bot;



1;