ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Net-IRC3/lib/Net/IRC3/Client/Connection.pm
Revision: 1.6
Committed: Mon Jul 17 16:11:32 2006 UTC (20 years, 3 months ago) by elmex
Branch: MAIN
Changes since 1.5: +1 -1 lines
Log Message:
fixed typo in copyright

File Contents

# User Rev Content
1 elmex 1.1 package Net::IRC3::Client::Connection;
2 elmex 1.4 use base "Net::IRC3::Connection";
3     use Net::IRC3::Util qw/prefix_nick/;
4 elmex 1.1
5 elmex 1.4 our $DEBUG;
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.5 L<Net::IRC3::Client::Connection> is a highlevel client connection,
46     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.2 =head1 EVENTS
51    
52     The following events are emitted by L<Net::IRC3::Client::Connection>.
53     Use C<reg_cb> as described in L<Net::IRC3::Connection> to register to such an
54     event.
55 elmex 1.1
56     =over 4
57    
58 elmex 1.3 =item B<registered>
59    
60     Emitted when the connection got successfully registered.
61    
62 elmex 1.2 =item B<channel_add $channel @nicks>
63    
64     Emitted when C<@nicks> are added to the channel C<$channel>,
65     this happens for example when someone JOINs a channel or when you
66     get a RPL_NAMREPLY (see RFC2812).
67    
68     =item B<channel_remove $channel @nicks>
69    
70     Emitted when C<@nicks> are removed from the channel C<$channel>,
71     happens for example when they PART, QUIT or get KICKed.
72    
73     =item B<join $nick $channel $is_myself>
74    
75     Emitted when C<$nick> enters the channel C<$channel> by JOINing.
76     C<$is_myself> is true if youself are the one who JOINs.
77    
78     =item B<part $nick $channel $is_myself $msg>
79    
80     Emitted when C<$nick> PARTs the channel C<$channel>.
81     C<$is_myself> is true if youself are the one who PARTs.
82     C<$msg> is the PART message.
83 elmex 1.1
84 elmex 1.3 =item B<quit $nick $msg>
85    
86     Emitted when the nickname C<$nick> QUITs with the message C<$msg>.
87    
88     =item B<publicmsg $channel $ircmsg>
89    
90     Emitted for NOTICE and PRIVMSG where the target C<$channel> is a channel.
91     C<$ircmsg> is the original IRC message hash like it is returned by C<parse_irc_msg>.
92    
93     =item B<privatemsg $nick $ircmsg>
94    
95     Emitted for NOTICE and PRIVMSG where the target C<$nick> (most of the time you) is a nick.
96     C<$ircmsg> is the original IRC message hash like it is returned by C<parse_irc_msg>.
97    
98 elmex 1.2 =back
99    
100     =head1 METHODS
101    
102     =over 4
103 elmex 1.1
104     =cut
105    
106 elmex 1.2 sub new {
107     my $this = shift;
108     my $class = ref($this) || $this;
109     my $self = $class->SUPER::new (@_);
110 elmex 1.1 $self->reg_cb (irc_001 => \&welcome_cb);
111     $self->reg_cb (irc_join => \&join_cb);
112     $self->reg_cb (irc_part => \&part_cb);
113 elmex 1.2 $self->reg_cb (irc_kick => \&kick_cb);
114     $self->reg_cb (irc_quit => \&quit_cb);
115 elmex 1.1 $self->reg_cb (irc_353 => \&namereply_cb);
116     $self->reg_cb (irc_366 => \&endofnames_cb);
117     $self->reg_cb (irc_ping => \&ping_cb);
118    
119     $self->reg_cb (irc_privmsg => \&privmsg_cb);
120     $self->reg_cb (irc_notice => \&privmsg_cb);
121    
122     $self->reg_cb ('irc_*' => \&debug_cb)
123     if $DEBUG;
124     $self->reg_cb ('irc_*' => \&anymsg_cb);
125    
126 elmex 1.2 $self->reg_cb (channel_remove => \&channel_remove_event);
127     $self->reg_cb (channel_add => \&channel_add_event);
128    
129     return $self;
130     }
131    
132     =item B<register ($nick, $user, $real)>
133    
134     Sends the IRC registration commands NICK and USER.
135    
136     =cut
137    
138     sub register {
139     my ($self, $nick, $user, $real) = @_;
140    
141 elmex 1.1 $self->send_msg (undef, "NICK", undef, $nick);
142     $self->send_msg (undef, "USER", $real || $nick, $user || $nick, "*", "0");
143    
144     $self->{nick} = $nick;
145     $self->{user} = $user;
146     $self->{real} = $real;
147     }
148    
149     =item B<nick ()>
150    
151     Returns the current nickname, under which this connection
152     is registered at the IRC server. It might be different from the
153     one that was passed to C<register> as a nick-collision might happened
154     on login.
155    
156     =cut
157    
158     sub nick { $_[0]->{nick} }
159    
160     =item B<channel_list ()>
161    
162 elmex 1.2 This returns a hash reference. The keys are the currently joined channels. The values
163     are hash references which contain the joined nicks as key.
164 elmex 1.1
165     =cut
166    
167     sub channel_list {
168     my ($self) = @_;
169 elmex 1.2 return $self->{channels};
170 elmex 1.1 }
171    
172 elmex 1.5 =item B<send_srv ($command, $trailing, @params)>
173 elmex 1.1
174 elmex 1.5 This function sends an IRC message that is constructed by C<mk_msg (undef, $command, $trailing, @params)> (see L<Net::IRC3::Util>).
175 elmex 1.1 If the connection isn't yet registered (for example if the connection is slow) and hasn't got a
176     welcome (IRC command 001) from the server yet, the IRC message is queued until it gets a welcome.
177    
178     =cut
179    
180     sub send_srv {
181     my ($self, @msg) = @_;
182    
183     if ($self->{connected}) {
184     $self->send_msg (undef, @msg);
185    
186     } else {
187     push @{$self->{con_queue}}, \@msg;
188     }
189     }
190    
191     =item B<clear_srv_queue>
192    
193     Clears the server send queue.
194    
195     =cut
196    
197     sub clear_srv_queue {
198     my ($self) = @_;
199     $self->{con_queue} = [];
200     }
201    
202    
203 elmex 1.5 =item B<send_chan ($channel, $command, $trailing, @params))>
204    
205     This function sends a message (constructed by C<mk_msg (undef, $command, $trailing, @params)>
206     to the server, like C<send_srv> only that it will queue the messages if it hasn't joined the
207     channel C<$channel> yet. The queued messages will be send once the connection successfully
208     JOINed the C<$channel>.
209 elmex 1.1
210     =cut
211    
212     sub send_chan {
213     my ($self, $chan, @msg) = @_;
214    
215 elmex 1.2 if ($self->{channels}->{lc $chan}) {
216 elmex 1.1 $self->send_msg (undef, @msg);
217    
218     } else {
219     push @{$self->{chan_queue}->{lc $chan}}, \@msg;
220     }
221     }
222    
223     =item B<clear_chan_queue ($channel)>
224    
225     Clears the channel queue of the channel C<$channel>.
226    
227     =cut
228    
229     sub clear_chan_queue {
230     my ($self, $chan) = @_;
231     $self->{chan_queue}->{lc $chan} = [];
232     }
233    
234     ################################################################################
235 elmex 1.2 # Private utility functions
236     ################################################################################
237    
238     sub _was_me {
239     my ($self, $msg) = @_;
240 elmex 1.4 lc prefix_nick ($msg) eq lc $self->nick ()
241 elmex 1.2 }
242    
243     ################################################################################
244 elmex 1.1 # Callbacks
245     ################################################################################
246    
247 elmex 1.2 sub channel_remove_event {
248     my ($self, $chan, @nicks) = @_;
249    
250     $chan = lc $chan;
251     for my $nick (@nicks) {
252     $nick = lc $nick;
253    
254     if ($nick eq lc $self->nick ()) {
255     delete $self->{chan_queue}->{$chan};
256     delete $self->{channels}->{$chan};
257     last;
258     } else {
259     delete $self->{channels}->{$chan}->{$nick};
260     }
261     }
262    
263     1;
264     }
265    
266     sub channel_add_event {
267     my ($self, $chan, @nicks) = @_;
268     $chan = lc $chan;
269    
270     for my $nick (@nicks) {
271     $nick = lc $nick;
272    
273     if ($nick eq lc $self->nick ()) {
274     for (@{$self->{chan_queue}->{$chan}}) {
275     $self->send_msg (undef, @$_);
276     }
277     }
278    
279     $self->{channels}->{$chan}->{$nick} = 1;
280     }
281    
282    
283     1;
284     }
285    
286 elmex 1.1 sub anymsg_cb {
287     my ($self, $msg) = @_;
288    
289     my $cmd = lc $msg->{command};
290    
291     if ( $cmd ne "privmsg"
292     and $cmd ne "notice"
293     and $cmd ne "part"
294     and $cmd ne "join"
295     )
296     {
297     $self->event (statmsg => $msg);
298     }
299    
300     1;
301     }
302    
303     sub privmsg_cb {
304     my ($self, $msg) = @_;
305    
306 elmex 1.3 my $targ = $msg->{params}->[0];
307     if ($targ =~ m/^(?:[#+&]|![A-Z0-9]{5})/) {
308     $self->event (publicmsg => $targ, $msg);
309 elmex 1.1
310     } else {
311 elmex 1.3 $self->event (privatemsg => $targ, $msg);
312 elmex 1.1 }
313    
314     1;
315     }
316    
317     sub welcome_cb {
318     my ($self, $msg) = @_;
319    
320     $self->{connected} = 1;
321    
322 elmex 1.2 $self->event ('registered');
323    
324 elmex 1.1 for (@{$self->{con_queue}}) {
325     $self->send_msg (undef, @$_);
326     }
327    
328     1;
329     }
330    
331     sub ping_cb {
332     my ($self, $msg) = @_;
333     $self->send_srv ("PONG", $msg->{params}->[0]);
334 elmex 1.2
335     1;
336 elmex 1.1 }
337    
338     sub namereply_cb {
339     my ($self, $msg) = @_;
340 elmex 1.2 my @nicks = split / /, $msg->{trailing};
341     push @{$self->{_tmp_namereply}}, @nicks;
342 elmex 1.1 }
343    
344     sub endofnames_cb {
345     my ($self, $msg) = @_;
346 elmex 1.2 my $chan = lc $msg->{params}->[1];
347 elmex 1.4 $self->event (channel_add => $chan, map { s/^[@\+]//; $_ } @{delete $self->{_tmp_namereply}});
348 elmex 1.1 }
349    
350     sub join_cb {
351     my ($self, $msg) = @_;
352 elmex 1.2 my $chan = $msg->{params}->[0];
353 elmex 1.4 my $nick = prefix_nick ($msg);
354 elmex 1.1
355 elmex 1.2 $self->event (join => $nick, $chan, $self->_was_me ($msg));
356     $self->event (channel_add => $chan, $nick);
357 elmex 1.1
358 elmex 1.2 1;
359     }
360    
361     sub part_cb {
362     my ($self, $msg) = @_;
363     my $chan = $msg->{params}->[0];
364 elmex 1.4 my $nick = prefix_nick ($msg);
365 elmex 1.1
366 elmex 1.2 $self->event (part => $nick, $chan, $self->_was_me ($msg), $msg->{params}->[1]);
367     $self->event (channel_remove => $chan, $nick);
368 elmex 1.1
369 elmex 1.2 1;
370     }
371 elmex 1.1
372 elmex 1.2 sub kick_cb {
373     my ($self, $msg) = @_;
374     my $chan = $msg->{params}->[0];
375     my $kicked_nick = $msg->{params}->[1];
376 elmex 1.1
377 elmex 1.2 $self->event (channel_remove => $chan, $kicked_nick);
378 elmex 1.1
379     1;
380     }
381    
382 elmex 1.2 sub quit_cb {
383 elmex 1.1 my ($self, $msg) = @_;
384 elmex 1.4 my $nick = prefix_nick ($msg);
385 elmex 1.1
386 elmex 1.2 $self->event (quit => $nick, $msg->{params}->[1]);
387 elmex 1.1
388 elmex 1.2 for (keys %{$self->{channels}}) {
389     $self->event (channel_remove => $_, $nick);
390 elmex 1.1 }
391     }
392    
393     sub debug_cb {
394     my ($self, $msg) = @_;
395     print "$self->{h}:$self->{p} > ";
396     my $par = delete $msg->{params};
397     print (join " ", map { $_ => $msg->{$_} } sort keys %$msg);
398     print " params:";
399     print (join ",", @$par);
400     print "\n";
401     }
402    
403     =back
404    
405     =head1 EXAMPLES
406    
407     See samples/netirc3cl and other samples in samples/ for some examples on how to use Net::IRC3::Client::Connection.
408    
409     =head1 AUTHOR
410    
411     Robin Redeker, C<< <elmex@ta-sa.org> >>
412    
413     =head1 SEE ALSO
414    
415     L<Net::IRC3>
416    
417     L<Net::IRC3::Client>
418    
419     L<Net::IRC3::Client::Connection>
420    
421     RFC 2812 - Internet Relay Chat: Client Protocol
422    
423     =head1 COPYRIGHT & LICENSE
424    
425 elmex 1.6 Copyright 2006 Robin Redeker, all rights reserved.
426 elmex 1.1
427     This program is free software; you can redistribute it and/or modify it
428     under the same terms as Perl itself.
429    
430     =cut
431    
432     1;