ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-IRC3/lib/Net/IRC3/Client/Connection.pm
Revision: 1.31
Committed: Sat Aug 18 12:39:02 2007 UTC (19 years, 2 months ago) by elmex
Branch: MAIN
Changes since 1.30: +10 -4 lines
Log Message:
implemented color filtering for irc

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