ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-IRC3/lib/Net/IRC3/Client/Connection.pm
Revision: 1.32
Committed: Mon Mar 17 19:40:38 2008 UTC (18 years, 7 months ago) by elmex
Branch: MAIN
Changes since 1.31: +23 -11 lines
Log Message:
some changes on the connection behaviour and a bugfix here and there

File Contents

# User Rev Content
1 elmex 1.1 package Net::IRC3::Client::Connection;
2 elmex 1.4 use base "Net::IRC3::Connection";
3 elmex 1.25 use Net::IRC3::Util qw/prefix_nick decode_ctcp/;
4 elmex 1.12 use strict;
5 elmex 1.17 no warnings;
6 elmex 1.1
7     =head1 NAME
8    
9     Net::IRC3::Client::Connection - A highlevel IRC connection
10    
11     =head1 SYNOPSIS
12    
13 elmex 1.5 use AnyEvent;
14     use Net::IRC3::Client::Connection;
15 elmex 1.1
16 elmex 1.5 my $c = AnyEvent->condvar;
17 elmex 1.1
18 elmex 1.5 my $timer;
19     my $con = new Net::IRC3::Client::Connection;
20 elmex 1.1
21 elmex 1.5 $con->reg_cb (registered => sub { print "I'm in!\n"; 0 });
22     $con->reg_cb (disconnect => sub { print "I'm out!\n"; 0 });
23     $con->reg_cb (
24     sent => sub {
25     if ($_[2] eq 'PRIVMSG') {
26     print "Sent message!\n";
27     $timer = AnyEvent->timer (after => 1, cb => sub { $c->broadcast });
28     }
29     1
30     }
31     );
32    
33     $con->send_srv (PRIVMSG => "Hello there i'm the cool Net::IRC3 test script!", 'elmex');
34    
35     $con->connect ("localhost", 6667);
36     $con->register (qw/testbot testbot testbot/);
37 elmex 1.1
38 elmex 1.5 $c->wait;
39     undef $timer;
40    
41     $con->disconnect;
42 elmex 1.1
43     =head1 DESCRIPTION
44    
45 elmex 1.25 L<Net::IRC3::Client::Connection> is a (nearly) highlevel client connection,
46 elmex 1.5 that manages all the stuff that noone wants to implement again and again
47     when handling with IRC. For example it PONGs the server or keeps track
48     of the users on a channel.
49 elmex 1.1
50 elmex 1.25 Please note that CTCP handling is still up to you. It will be decoded
51     for you and events will be generated. But generating replies
52     is up to you.
53    
54 elmex 1.13 =head2 A NOTE TO CASE MANAGEMENT
55    
56     The case insensitivity of channelnames and nicknames can lead to headaches
57     when dealing with IRC in an automated client which tracks channels and nicknames.
58    
59     I tried to preserve the case in all channel and nicknames
60     Net::IRC3::Client::Connection passes to his user. But in the internal
61     structures i'm using lower case for the channel names.
62    
63     The returned hash from C<channel_list> for example has the lower case of the
64     joined channels as keys.
65    
66     But i tried to preserve the case in all events that are emitted.
67     Please keep this in mind when handling the events.
68    
69     For example a user might joins #TeSt and parts #test later.
70    
71 elmex 1.2 =head1 EVENTS
72    
73     The following events are emitted by L<Net::IRC3::Client::Connection>.
74     Use C<reg_cb> as described in L<Net::IRC3::Connection> to register to such an
75     event.
76 elmex 1.1
77     =over 4
78    
79 elmex 1.3 =item B<registered>
80    
81     Emitted when the connection got successfully registered.
82    
83 elmex 1.32 =item B<channel_add $msg, $channel @nicks>
84 elmex 1.2
85     Emitted when C<@nicks> are added to the channel C<$channel>,
86     this happens for example when someone JOINs a channel or when you
87     get a RPL_NAMREPLY (see RFC2812).
88    
89 elmex 1.32 C<$msg> ist he IRC message hash that as returned by C<parse_irc_msg>.
90    
91     =item B<channel_remove $msg, $channel @nicks>
92 elmex 1.2
93     Emitted when C<@nicks> are removed from the channel C<$channel>,
94     happens for example when they PART, QUIT or get KICKed.
95    
96 elmex 1.32 C<$msg> ist he IRC message hash that as returned by C<parse_irc_msg>
97     or undef if the reason for the removal was a disconnect on our end.
98    
99 elmex 1.13 =item B<channel_change $channel $old_nick $new_nick $is_myself>
100    
101     Emitted when a nickname on a channel changes. This is emitted when a NICK
102     change occurs from C<$old_nick> to C<$new_nick> give the application a chance
103     to quickly analyze what channels were affected. C<$is_myself> is true when
104     youself was the one who changed the nick.
105    
106 elmex 1.23 =item B<channel_topic $channel $topic $who>
107    
108     This is emitted when the topic for a channel is discovered. C<$channel>
109     is the channel for which C<$topic> is the current topic now.
110     Which is set by C<$who>. C<$who> might be undefined when it's not known
111     who set the channel topic.
112    
113 elmex 1.2 =item B<join $nick $channel $is_myself>
114    
115     Emitted when C<$nick> enters the channel C<$channel> by JOINing.
116     C<$is_myself> is true if youself are the one who JOINs.
117    
118     =item B<part $nick $channel $is_myself $msg>
119    
120     Emitted when C<$nick> PARTs the channel C<$channel>.
121     C<$is_myself> is true if youself are the one who PARTs.
122     C<$msg> is the PART message.
123 elmex 1.1
124 elmex 1.32 =item B<part $kicked_nick $channel $is_myself $msg>
125    
126     Emitted when C<$kicked_nick> is KICKed from the channel C<$channel>.
127     C<$is_myself> is true if youself are the one who got KICKed.
128     C<$msg> is the PART message.
129    
130 elmex 1.13 =item B<nick_change $old_nick $new_nick $is_myself>
131 elmex 1.12
132     Emitted when C<$old_nick> is renamed to C<$new_nick>.
133     C<$is_myself> is true when youself was the one who changed the nick.
134    
135 elmex 1.25 =item B<ctcp $src, $target, $tag, $msg, $type>
136    
137     Emitted when a CTCP message was found in either a NOTICE or PRIVMSG
138     message. C<$tag> is the CTCP message tag. (eg. "PING", "VERSION", ...).
139     C<$msg> is the CTCP message and C<$type> is either "NOTICE" or "PRIVMSG".
140    
141     C<$src> is the source nick the message came from.
142     C<$target> is the target nickname (yours) or the channel the ctcp was sent
143     on.
144    
145     =item B<"ctcp_$tag", $src, $target, $msg, $type>
146    
147     Emitted when a CTCP message was found in either a NOTICE or PRIVMSG
148 elmex 1.26 message. C<$tag> is the CTCP message tag (in lower case). (eg. "ping", "version", ...).
149 elmex 1.25 C<$msg> is the CTCP message and C<$type> is either "NOTICE" or "PRIVMSG".
150    
151     C<$src> is the source nick the message came from.
152     C<$target> is the target nickname (yours) or the channel the ctcp was sent
153     on.
154    
155 elmex 1.3 =item B<quit $nick $msg>
156    
157     Emitted when the nickname C<$nick> QUITs with the message C<$msg>.
158    
159     =item B<publicmsg $channel $ircmsg>
160    
161     Emitted for NOTICE and PRIVMSG where the target C<$channel> is a channel.
162     C<$ircmsg> is the original IRC message hash like it is returned by C<parse_irc_msg>.
163    
164 elmex 1.25 The trailing part of the C<$ircmsg> will have all CTCP messages stripped off.
165    
166 elmex 1.3 =item B<privatemsg $nick $ircmsg>
167    
168     Emitted for NOTICE and PRIVMSG where the target C<$nick> (most of the time you) is a nick.
169     C<$ircmsg> is the original IRC message hash like it is returned by C<parse_irc_msg>.
170    
171 elmex 1.25 The trailing part of the C<$ircmsg> will have all CTCP messages stripped off.
172    
173 elmex 1.21 =item B<error $code $message $ircmsg>
174 elmex 1.13
175     Emitted when any error occurs. C<$code> is the 3 digit error id string from RFC
176 elmex 1.21 2812 and C<$message> is a description of the error. C<$ircmsg> is the complete
177     error irc message.
178 elmex 1.13
179     You may use Net::IRC3::Util::rfc_code_to_name to convert C<$code> to the error
180     name from the RFC 2812. eg.:
181    
182     rfc_code_to_name ('471') => 'ERR_CHANNELISFULL'
183    
184 elmex 1.30 =item B<debug_send $prefix $command $trailing @params>
185 elmex 1.29
186     Is emitted everytime some command is sent.
187    
188     =item B<debug_recv $ircmsg>
189    
190     Is emitted everytime some command was received.
191    
192 elmex 1.2 =back
193    
194     =head1 METHODS
195    
196     =over 4
197 elmex 1.1
198 elmex 1.16 =item B<new>
199    
200     This constructor takes no arguments.
201    
202 elmex 1.1 =cut
203    
204 elmex 1.2 sub new {
205     my $this = shift;
206     my $class = ref($this) || $this;
207     my $self = $class->SUPER::new (@_);
208 elmex 1.29
209 elmex 1.30 $self->reg_cb ('irc_*' => \&debug_cb);
210 elmex 1.1 $self->reg_cb (irc_001 => \&welcome_cb);
211     $self->reg_cb (irc_join => \&join_cb);
212 elmex 1.12 $self->reg_cb (irc_nick => \&nick_cb);
213 elmex 1.1 $self->reg_cb (irc_part => \&part_cb);
214 elmex 1.2 $self->reg_cb (irc_kick => \&kick_cb);
215     $self->reg_cb (irc_quit => \&quit_cb);
216 elmex 1.1 $self->reg_cb (irc_353 => \&namereply_cb);
217     $self->reg_cb (irc_366 => \&endofnames_cb);
218     $self->reg_cb (irc_ping => \&ping_cb);
219 elmex 1.27 $self->reg_cb (irc_pong => \&pong_cb);
220 elmex 1.1
221     $self->reg_cb (irc_privmsg => \&privmsg_cb);
222     $self->reg_cb (irc_notice => \&privmsg_cb);
223    
224     $self->reg_cb ('irc_*' => \&anymsg_cb);
225    
226 elmex 1.16 $self->reg_cb (channel_remove => \&channel_remove_event_cb);
227     $self->reg_cb (channel_add => \&channel_add_event_cb);
228     $self->reg_cb (disconnect => \&disconnect_cb);
229 elmex 1.2
230 elmex 1.16 $self->reg_cb (irc_437 => \&change_nick_login_cb);
231     $self->reg_cb (irc_433 => \&change_nick_login_cb);
232 elmex 1.13
233 elmex 1.23 $self->reg_cb (irc_332 => \&rpl_topic_cb);
234     $self->reg_cb (irc_topic => \&topic_change_cb);
235    
236 elmex 1.17 $self->{def_nick_change} = $self->{nick_change} =
237     sub {
238     my ($old_nick) = @_;
239     "${old_nick}_"
240     };
241 elmex 1.13
242 elmex 1.2 return $self;
243     }
244    
245 elmex 1.24 =item B<register ($nick, $user, $real, $server_pass)>
246 elmex 1.2
247     Sends the IRC registration commands NICK and USER.
248 elmex 1.24 If C<$server_pass> is passed also a PASS command is generated.
249 elmex 1.2
250     =cut
251    
252     sub register {
253 elmex 1.24 my ($self, $nick, $user, $real, $pass) = @_;
254 elmex 1.2
255 elmex 1.13 $self->{nick} = $nick;
256     $self->{user} = $user;
257     $self->{real} = $real;
258 elmex 1.24 $self->{server_pass} = $pass;
259 elmex 1.13
260 elmex 1.24 $self->send_msg (undef, "PASS", undef, $pass) if defined $pass;
261 elmex 1.1 $self->send_msg (undef, "NICK", undef, $nick);
262     $self->send_msg (undef, "USER", $real || $nick, $user || $nick, "*", "0");
263 elmex 1.13 }
264    
265     =item B<set_nick_change_cb $callback>
266    
267     This method lets you modify the nickname renaming mechanism when registering
268     the connection. C<$callback> is called with the current nickname as first
269     argument when a ERR_NICKNAMEINUSE or ERR_UNAVAILRESOURCE error occurs on login.
270     The returnvalue of C<$callback> will then be used to change the nickname.
271    
272 elmex 1.17 If C<$callback> is not defined the default nick change callback will be used
273     again.
274    
275 elmex 1.13 The default callback appends '_' to the end of the nickname supplied in the
276     C<register> routine.
277    
278     If the callback returns the same nickname that was given it the connection
279     will be terminated.
280 elmex 1.1
281 elmex 1.13 =cut
282    
283     sub set_nick_change_cb {
284     my ($self, $cb) = @_;
285 elmex 1.17 $cb = $self->{def_nick_change} unless defined $cb;
286 elmex 1.13 $self->{nick_change} = $cb;
287 elmex 1.1 }
288    
289     =item B<nick ()>
290    
291     Returns the current nickname, under which this connection
292     is registered at the IRC server. It might be different from the
293     one that was passed to C<register> as a nick-collision might happened
294     on login.
295    
296     =cut
297    
298     sub nick { $_[0]->{nick} }
299    
300 elmex 1.17 =item B<registered ()>
301 elmex 1.13
302     Returns a true value when the connection has been registered successfull and
303     you can send commands.
304    
305     =cut
306    
307 elmex 1.17 sub registered { $_[0]->{registered} }
308 elmex 1.13
309 elmex 1.1 =item B<channel_list ()>
310    
311 elmex 1.13 This returns a hash reference. The keys are the currently joined channels in lower case.
312     The values are hash references which contain the joined nicks as key.
313    
314     NOTE: Future versions might preserve the case from the JOIN command to the channels.
315 elmex 1.1
316     =cut
317    
318     sub channel_list {
319     my ($self) = @_;
320 elmex 1.12 return $self->{channel_list} || {};
321 elmex 1.1 }
322    
323 elmex 1.31 =item B<send_msg (...)>
324 elmex 1.1
325 elmex 1.31 See also L<Net::IRC3::Connection>.
326 elmex 1.1
327     =cut
328    
329 elmex 1.27 sub send_msg {
330     my ($self, @a) = @_;
331 elmex 1.29 $self->event (debug_send => @a);
332 elmex 1.27 $self->SUPER::send_msg (@a);
333     }
334    
335 elmex 1.31 =item B<send_srv ($command, $trailing, @params)>
336    
337     This function sends an IRC message that is constructed by C<mk_msg (undef, $command, $trailing, @params)> (see L<Net::IRC3::Util>).
338     If the connection isn't yet registered (for example if the connection is slow) and hasn't got a
339     welcome (IRC command 001) from the server yet, the IRC message is queued until it gets a welcome.
340    
341     =cut
342    
343 elmex 1.1 sub send_srv {
344     my ($self, @msg) = @_;
345    
346 elmex 1.17 if ($self->registered) {
347 elmex 1.1 $self->send_msg (undef, @msg);
348    
349     } else {
350     push @{$self->{con_queue}}, \@msg;
351     }
352     }
353    
354     =item B<clear_srv_queue>
355    
356     Clears the server send queue.
357    
358     =cut
359    
360     sub clear_srv_queue {
361     my ($self) = @_;
362     $self->{con_queue} = [];
363     }
364    
365    
366 elmex 1.5 =item B<send_chan ($channel, $command, $trailing, @params))>
367    
368 elmex 1.13 This function sends a message (constructed by C<mk_msg (undef, $command,
369     $trailing, @params)> to the server, like C<send_srv> only that it will queue
370     the messages if it hasn't joined the channel C<$channel> yet. The queued
371     messages will be send once the connection successfully JOINed the C<$channel>.
372 elmex 1.1
373 elmex 1.12 C<$channel> will be lowercased so that any case that comes from the server matches.
374     (Yes, IRC handles upper and lower case as equal :-(
375    
376     Be careful with this, there are chances you might not join the channel you
377     wanted to join. You may wanted to join #bla and the server redirects that
378     and sends you that you joined #blubb. You may use C<clear_chan_queue> to
379     remove the queue after some timeout after joining, so that you don't end up
380     with a memory leak.
381    
382 elmex 1.1 =cut
383    
384     sub send_chan {
385     my ($self, $chan, @msg) = @_;
386    
387 elmex 1.14 if ($self->{channel_list}->{lc $chan}) {
388 elmex 1.1 $self->send_msg (undef, @msg);
389    
390     } else {
391     push @{$self->{chan_queue}->{lc $chan}}, \@msg;
392     }
393     }
394    
395     =item B<clear_chan_queue ($channel)>
396    
397     Clears the channel queue of the channel C<$channel>.
398    
399     =cut
400    
401     sub clear_chan_queue {
402     my ($self, $chan) = @_;
403     $self->{chan_queue}->{lc $chan} = [];
404     }
405    
406 elmex 1.27 =item B<enable_ping ($interval, $cb)>
407    
408     This method enables a periodical ping to the server with an interval of
409     C<$interval> seconds. If no PONG was received from the server until the next
410     interval the connection will be terminated or the callback in C<$cb> will be called.
411    
412     (C<$cb> will have the connection object as it's first argument.)
413    
414     Make sure you call this method after the connection has been established.
415 elmex 1.28 (eg. in the callback for the C<registered> event).
416 elmex 1.27
417     =cut
418    
419     sub enable_ping {
420     my ($self, $int, $cb) = @_;
421    
422     $self->{last_pong_recv} = 0;
423     $self->{last_ping_sent} = time;
424    
425     $self->send_srv (PING => "Net::IRC3");
426    
427     $self->{_ping_timer} =
428     AnyEvent->timer (after => $int, cb => sub {
429     if ($self->{last_pong_recv} < $self->{last_ping_sent}) {
430     delete $self->{_ping_timer};
431     if ($cb) {
432     $cb->($self);
433     } else {
434     $self->disconnect ("Server timeout");
435     }
436    
437     } else {
438     $self->enable_ping ($int, $cb);
439     }
440     });
441     }
442    
443 elmex 1.1 ################################################################################
444 elmex 1.2 # Private utility functions
445     ################################################################################
446    
447     sub _was_me {
448     my ($self, $msg) = @_;
449 elmex 1.4 lc prefix_nick ($msg) eq lc $self->nick ()
450 elmex 1.2 }
451    
452     ################################################################################
453 elmex 1.1 # Callbacks
454     ################################################################################
455    
456 elmex 1.16 sub channel_remove_event_cb {
457 elmex 1.32 my ($self, $msg, $chan, @nicks) = @_;
458 elmex 1.2
459     for my $nick (@nicks) {
460 elmex 1.12 if (lc ($nick) eq lc ($self->nick ())) {
461     delete $self->{chan_queue}->{lc $chan};
462 elmex 1.13 delete $self->{channel_list}->{lc $chan};
463 elmex 1.2 last;
464     } else {
465 elmex 1.13 delete $self->{channel_list}->{lc $chan}->{$nick};
466 elmex 1.2 }
467     }
468    
469     1;
470     }
471    
472 elmex 1.16 sub channel_add_event_cb {
473 elmex 1.32 my ($self, $msg, $chan, @nicks) = @_;
474 elmex 1.2
475     for my $nick (@nicks) {
476 elmex 1.12 if (lc ($nick) eq lc ($self->nick ())) {
477     for (@{$self->{chan_queue}->{lc $chan}}) {
478 elmex 1.2 $self->send_msg (undef, @$_);
479     }
480 elmex 1.11 $self->clear_chan_queue ($chan);
481 elmex 1.2 }
482    
483 elmex 1.13 $self->{channel_list}->{lc $chan}->{$nick} = 1;
484 elmex 1.2 }
485    
486     1;
487     }
488    
489 elmex 1.19 sub _filter_new_nicks_from_channel {
490     my ($self, $chan, @nicks) = @_;
491     grep { not exists $self->{channel_list}->{lc $chan}->{$_} } @nicks;
492     }
493    
494 elmex 1.1 sub anymsg_cb {
495     my ($self, $msg) = @_;
496    
497     my $cmd = lc $msg->{command};
498    
499 elmex 1.13 if ( $cmd ne "privmsg"
500 elmex 1.1 and $cmd ne "notice"
501     and $cmd ne "part"
502     and $cmd ne "join"
503 elmex 1.13 and not ($cmd >= 400 and $cmd <= 599)
504     )
505 elmex 1.1 {
506     $self->event (statmsg => $msg);
507 elmex 1.13 } elsif ($cmd >= 400 and $cmd <= 599) {
508 elmex 1.21 $self->event (error => $msg->{command}, $msg->{trailing}, $msg);
509 elmex 1.1 }
510    
511     1;
512     }
513    
514     sub privmsg_cb {
515     my ($self, $msg) = @_;
516    
517 elmex 1.25 my ($trail, $ctcp) = decode_ctcp ($msg->{trailing});
518    
519     for (@$ctcp) {
520     $self->event (ctcp => prefix_nick ($msg), $msg->{params}->[0], $_->[0], $_->[1], $msg->{command});
521 elmex 1.32 $self->event ("ctcp_".lc ($_->[0]), prefix_nick ($msg), $msg->{params}->[0], $_->[1], $msg->{command});
522 elmex 1.25 }
523    
524     $msg->{trailing} = $trail;
525 elmex 1.1
526 elmex 1.25 if ($msg->{trailing} ne '') {
527     my $targ = $msg->{params}->[0];
528     if ($targ =~ m/^(?:[#+&]|![A-Z0-9]{5})/) {
529     $self->event (publicmsg => $targ, $msg);
530    
531     } else {
532     $self->event (privatemsg => $targ, $msg);
533     }
534 elmex 1.1 }
535    
536     1;
537     }
538    
539     sub welcome_cb {
540     my ($self, $msg) = @_;
541    
542 elmex 1.17 $self->{registered} = 1;
543 elmex 1.1
544     for (@{$self->{con_queue}}) {
545     $self->send_msg (undef, @$_);
546     }
547 elmex 1.11 $self->clear_srv_queue ();
548 elmex 1.1
549 elmex 1.12 $self->event ('registered');
550    
551 elmex 1.1 1;
552     }
553    
554     sub ping_cb {
555     my ($self, $msg) = @_;
556 elmex 1.8 $self->send_msg (undef, "PONG", $msg->{params}->[0]);
557 elmex 1.2
558     1;
559 elmex 1.1 }
560    
561 elmex 1.27 sub pong_cb {
562     my ($self, $msg) = @_;
563     $self->{last_pong_recv} = time;
564     1;
565     }
566    
567 elmex 1.12 sub nick_cb {
568     my ($self, $msg) = @_;
569     my $nick = prefix_nick ($msg);
570     my $newnick = $msg->{params}->[0];
571     my $wasme = $self->_was_me ($msg);
572    
573 elmex 1.13 if ($wasme) { $self->{nick} = $newnick }
574 elmex 1.12
575 elmex 1.13 my @chans;
576 elmex 1.12
577 elmex 1.13 for my $channame (keys %{$self->{channel_list}}) {
578     my $chan = $self->{channel_list}->{$channame};
579 elmex 1.12 if (exists $chan->{$nick}) {
580     delete $chan->{$nick};
581     $chan->{$newnick} = 1;
582 elmex 1.23
583 elmex 1.13 push @chans, $channame;
584 elmex 1.12 }
585     }
586    
587 elmex 1.13 for (@chans) {
588     $self->event (channel_change => $_, $nick, $newnick, $wasme);
589     }
590 elmex 1.12 $self->event (nick_change => $nick, $newnick, $wasme);
591 elmex 1.23
592     1;
593 elmex 1.12 }
594    
595 elmex 1.1 sub namereply_cb {
596     my ($self, $msg) = @_;
597 elmex 1.2 my @nicks = split / /, $msg->{trailing};
598     push @{$self->{_tmp_namereply}}, @nicks;
599 elmex 1.10
600     1;
601 elmex 1.1 }
602    
603     sub endofnames_cb {
604     my ($self, $msg) = @_;
605 elmex 1.12 my $chan = $msg->{params}->[1];
606 elmex 1.20 my @nicks =
607 elmex 1.19 $self->_filter_new_nicks_from_channel (
608 elmex 1.28 $chan, map { s/^[~@\+%&]//; $_ } @{delete $self->{_tmp_namereply}}
609 elmex 1.20 );
610    
611 elmex 1.32 $self->event (channel_add => $msg, $chan, @nicks) if @nicks;
612 elmex 1.10
613     1;
614 elmex 1.1 }
615    
616     sub join_cb {
617     my ($self, $msg) = @_;
618 elmex 1.2 my $chan = $msg->{params}->[0];
619 elmex 1.4 my $nick = prefix_nick ($msg);
620 elmex 1.1
621 elmex 1.32 $self->event (channel_add => $msg, $chan, $nick);
622 elmex 1.2 $self->event (join => $nick, $chan, $self->_was_me ($msg));
623 elmex 1.1
624 elmex 1.2 1;
625     }
626    
627     sub part_cb {
628     my ($self, $msg) = @_;
629     my $chan = $msg->{params}->[0];
630 elmex 1.4 my $nick = prefix_nick ($msg);
631 elmex 1.1
632 elmex 1.2 $self->event (part => $nick, $chan, $self->_was_me ($msg), $msg->{params}->[1]);
633 elmex 1.32 $self->event (channel_remove => $msg, $chan, $nick);
634 elmex 1.1
635 elmex 1.2 1;
636     }
637 elmex 1.1
638 elmex 1.2 sub kick_cb {
639     my ($self, $msg) = @_;
640     my $chan = $msg->{params}->[0];
641     my $kicked_nick = $msg->{params}->[1];
642 elmex 1.1
643 elmex 1.32 $self->event (kick => $kicked_nick, $chan, $self->_was_me ($msg), $msg->{params}->[1]);
644     $self->event (channel_remove => $msg, $chan, $kicked_nick);
645 elmex 1.1
646     1;
647     }
648    
649 elmex 1.2 sub quit_cb {
650 elmex 1.1 my ($self, $msg) = @_;
651 elmex 1.4 my $nick = prefix_nick ($msg);
652 elmex 1.1
653 elmex 1.2 $self->event (quit => $nick, $msg->{params}->[1]);
654 elmex 1.1
655 elmex 1.12 for (keys %{$self->{channel_list}}) {
656 elmex 1.32 $self->event (channel_remove => $msg, $_, $nick)
657 elmex 1.14 if $self->{channel_list}->{$_}->{$nick};
658 elmex 1.1 }
659 elmex 1.10
660     1;
661 elmex 1.1 }
662    
663     sub debug_cb {
664     my ($self, $msg) = @_;
665 elmex 1.29 $self->event (debug_recv => $msg);
666     #print "$self->{h}:$self->{p} > ";
667     #print (join " ", map { $_ => $msg->{$_} } grep { $_ ne 'params' } sort keys %$msg);
668     #print " params:";
669     #print (join ",", @{$msg->{params}});
670     #print "\n";
671 elmex 1.10
672     1;
673 elmex 1.1 }
674    
675 elmex 1.16 sub change_nick_login_cb {
676 elmex 1.13 my ($self, $msg) = @_;
677    
678 elmex 1.17 unless ($self->registered) {
679 elmex 1.13 my $newnick = $self->{nick_change}->($self->nick);
680    
681     if (lc $newnick eq lc $self->{nick}) {
682     $self->disconnect;
683     return 0;
684     }
685    
686     $self->{nick} = $newnick;
687     $self->send_msg (undef, "NICK", undef, $newnick);
688     }
689    
690 elmex 1.17 not ($self->registered) # kill the cb when registered
691 elmex 1.13 }
692    
693 elmex 1.15 sub disconnect_cb {
694     my ($self) = @_;
695    
696     for (keys %{$self->{channel_list}}) {
697 elmex 1.32 $self->event (channel_remove => undef, $_, $self->nick)
698 elmex 1.15 }
699    
700     1
701     }
702    
703 elmex 1.23 sub rpl_topic_cb {
704     my ($self, $msg) = @_;
705     my $chan = $msg->{params}->[1];
706     my $topic = $msg->{trailing};
707    
708     $self->event (channel_topic => $chan, $topic);
709    
710     1
711     }
712    
713     sub topic_change_cb {
714     my ($self, $msg) = @_;
715     my $who = prefix_nick ($msg);
716     my $chan = $msg->{params}->[0];
717     my $topic = $msg->{trailing};
718    
719     $self->event (channel_topic => $chan, $topic, $who);
720    
721     1
722     }
723    
724 elmex 1.1 =back
725    
726     =head1 EXAMPLES
727    
728     See samples/netirc3cl and other samples in samples/ for some examples on how to use Net::IRC3::Client::Connection.
729    
730     =head1 AUTHOR
731    
732     Robin Redeker, C<< <elmex@ta-sa.org> >>
733    
734     =head1 SEE ALSO
735    
736 elmex 1.7 L<Net::IRC3::Connection>
737 elmex 1.1
738     RFC 2812 - Internet Relay Chat: Client Protocol
739    
740     =head1 COPYRIGHT & LICENSE
741    
742 elmex 1.6 Copyright 2006 Robin Redeker, all rights reserved.
743 elmex 1.1
744     This program is free software; you can redistribute it and/or modify it
745     under the same terms as Perl itself.
746    
747     =cut
748    
749     1;