package Net::IRC3::Client; use Net::IRC3; our $DEBUG = 0; sub new { my $this = shift; my $class = ref($this) || $this; my $self = { cfg => { @_ }, pirc => Net::IRC3->new }; bless $self, $class; return $self; } sub connect { my ($self, $host, $port, $nick, $user, $real) = @_; my $ncon; my $con = $self->{pirc}->connect_server ($host, $port, $self); my $ncon = $self->{conns}->{"$host:$port"} = Net::IRC3::Client::Connection->new ( $self->{pirc}, $con, $host, $port, $nick, $user, $real ); return $ncon; } sub connections { my ($self) = @_; return %{$self->{conns}}; } sub connection { my ($self, $host, $port) = @_; if ($host =~ m/^[^:]+:(\d+)$/) { return $self->{conns}->{$host} } else { return $self->{conns}->{$host.':'.$port} } } package Net::IRC3::Client::Connection; use Net::IRC3; sub new { my $this = shift; my $class = ref($this) || $this; my $self = { pirc => $_[0], con => $_[1], host => $_[2], port => $_[3], nick => lc $_[4], user => lc $_[5], real => $_[6] }; bless $self, $class; return $self; } sub nick { $_[0]->{nick} } sub disconnect { my ($self) = @_; $self->{con}->disconnect_server; } sub disconnect_cb { my ($self) = @_; delete $self->{con}; delete $self->{pirc}; } sub register { my ($self) = @_; my ($con, $nick, $user, $real) = @$self{qw/con nick user real/}; $self->reg_cb (irc_001 => \&welcome_cb); $self->reg_cb (irc_join => \&join_cb); $self->reg_cb (irc_part => \&part_cb); $self->reg_cb (irc_353 => \&namereply_cb); $self->reg_cb (irc_366 => \&endofnames_cb); $self->reg_cb (irc_ping => \&ping_cb); $self->reg_cb (irc_privmsg => \&privmsg_cb); $self->reg_cb (irc_notice => \&privmsg_cb); $self->reg_cb ('irc_*' => \&debug_cb) if $DEBUG; $self->reg_cb ('irc_*' => \&anymsg_cb); $self->reg_cb (disconnect => \&disconnect_cb); $con->send_msg (undef, "NICK", undef, $nick); $con->send_msg (undef, "USER", $real || $nick, $user || $nick, "*", "0"); } sub send_srv { my ($self, @msg) = @_; if ($self->{connected}) { $self->{con}->send_msg (undef, @msg); } else { push @{$self->{con_queue}}, \@msg; } } sub send_chan { my ($self, $chan, @msg) = @_; if ($self->{channels}->{$chan}) { $self->{con}->send_msg (undef, @msg); } else { push @{$self->{chan_queue}->{lc $chan}}, \@msg; } } sub anymsg_cb { my ($self, $msg) = @_; my $cmd = lc $msg->{command}; if ( $cmd ne "privmsg" and $cmd ne "notice" and $cmd ne "part" and $cmd ne "join" ) { $self->event (statmsg => $msg); } 1; } sub privmsg_cb { my ($self, $msg) = @_; if ($msg->{params}->[0] =~ m/^[#!]/) { $self->event (chanmsg => $msg->{params}->[0], $msg); } else { $self->event (querymsg => $msg->{params}->[0], $msg); } 1; } sub welcome_cb { my ($self, $msg) = @_; $self->{connected} = 1; for (@{$self->{con_queue}}) { $self->{con}->send_msg (undef, @$_); $self->event (connected => $chan); } 1; } sub ping_cb { my ($self, $msg) = @_; $self->send_srv ("PONG", $msg->{params}->[0]); } sub namereply_cb { my ($self, $msg) = @_; } sub endofnames_cb { my ($self, $msg) = @_; } sub reg_cb { my ($self, $cmd, $cb) = @_; $self->{con}->reg_cb ($cmd => sub { my ($_self) = shift; $cb->($self, @_) }); } sub event { my ($self, $ev, @args) = @_; $self->{con}->event ($ev => @args); } sub join_cb { my ($self, $msg) = @_; my $chan = lc $msg->{params}->[0]; $self->{channels}->{$chan} = {}; if (lc Net::IRC3::prefix_nick ($msg) eq lc $self->{nick}) { for (@{$self->{chan_queue}->{$chan}}) { $self->{con}->send_msg (undef, @$_); } $self->event (join => Net::IRC3::prefix_nick ($msg), $chan, 1); } else { $self->event (join => Net::IRC3::prefix_nick ($msg), $chan, 0); } 1; } sub channel_list { my ($self) = @_; return keys %{$self->{channels}}; } sub part_cb { my ($self, $msg) = @_; my $chan = lc $msg->{params}->[0]; my $nick = lc Net::IRC3::prefix_nick ($msg); if ($self->{nick} eq $nick) { delete $self->{chan_queue}->{$chan}; delete $self->{channels}->{$chan}; $self->event (part => Net::IRC3::prefix_nick ($msg), $chan, 1, $msg->{params}->[1]); } else { $self->event (part => Net::IRC3::prefix_nick ($msg), $chan, 0, $msg->{params}->[1]); } 1; } sub debug_cb { my ($self, $msg) = @_; print "$self->{host}:$self->{port} > "; my $par = delete $msg->{params}; print (join " ", map { $_ => $msg->{$_} } sort keys %$msg); print " params:"; print (join ",", @$par); print "\n"; } 1;