ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/Net-IRC3/lib/Net/IRC3/Client/Connection.pm
Revision: 1.10
Committed: Sun Oct 29 23:48:07 2006 UTC (20 years ago) by elmex
Branch: MAIN
Changes since 1.9: +8 -0 lines
Log Message:
added some 1;

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.9 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 elmex 1.8 $self->send_msg (undef, "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.10
343     1;
344 elmex 1.1 }
345    
346     sub endofnames_cb {
347     my ($self, $msg) = @_;
348 elmex 1.2 my $chan = lc $msg->{params}->[1];
349 elmex 1.4 $self->event (channel_add => $chan, map { s/^[@\+]//; $_ } @{delete $self->{_tmp_namereply}});
350 elmex 1.10
351     1;
352 elmex 1.1 }
353    
354     sub join_cb {
355     my ($self, $msg) = @_;
356 elmex 1.2 my $chan = $msg->{params}->[0];
357 elmex 1.4 my $nick = prefix_nick ($msg);
358 elmex 1.1
359 elmex 1.2 $self->event (join => $nick, $chan, $self->_was_me ($msg));
360     $self->event (channel_add => $chan, $nick);
361 elmex 1.1
362 elmex 1.2 1;
363     }
364    
365     sub part_cb {
366     my ($self, $msg) = @_;
367     my $chan = $msg->{params}->[0];
368 elmex 1.4 my $nick = prefix_nick ($msg);
369 elmex 1.1
370 elmex 1.2 $self->event (part => $nick, $chan, $self->_was_me ($msg), $msg->{params}->[1]);
371     $self->event (channel_remove => $chan, $nick);
372 elmex 1.1
373 elmex 1.2 1;
374     }
375 elmex 1.1
376 elmex 1.2 sub kick_cb {
377     my ($self, $msg) = @_;
378     my $chan = $msg->{params}->[0];
379     my $kicked_nick = $msg->{params}->[1];
380 elmex 1.1
381 elmex 1.2 $self->event (channel_remove => $chan, $kicked_nick);
382 elmex 1.1
383     1;
384     }
385    
386 elmex 1.2 sub quit_cb {
387 elmex 1.1 my ($self, $msg) = @_;
388 elmex 1.4 my $nick = prefix_nick ($msg);
389 elmex 1.1
390 elmex 1.2 $self->event (quit => $nick, $msg->{params}->[1]);
391 elmex 1.1
392 elmex 1.2 for (keys %{$self->{channels}}) {
393     $self->event (channel_remove => $_, $nick);
394 elmex 1.1 }
395 elmex 1.10
396     1;
397 elmex 1.1 }
398    
399     sub debug_cb {
400     my ($self, $msg) = @_;
401     print "$self->{h}:$self->{p} > ";
402     my $par = delete $msg->{params};
403     print (join " ", map { $_ => $msg->{$_} } sort keys %$msg);
404     print " params:";
405     print (join ",", @$par);
406     print "\n";
407 elmex 1.10
408     1;
409 elmex 1.1 }
410    
411     =back
412    
413     =head1 EXAMPLES
414    
415     See samples/netirc3cl and other samples in samples/ for some examples on how to use Net::IRC3::Client::Connection.
416    
417     =head1 AUTHOR
418    
419     Robin Redeker, C<< <elmex@ta-sa.org> >>
420    
421     =head1 SEE ALSO
422    
423 elmex 1.7 L<Net::IRC3::Connection>
424 elmex 1.1
425     RFC 2812 - Internet Relay Chat: Client Protocol
426    
427     =head1 COPYRIGHT & LICENSE
428    
429 elmex 1.6 Copyright 2006 Robin Redeker, all rights reserved.
430 elmex 1.1
431     This program is free software; you can redistribute it and/or modify it
432     under the same terms as Perl itself.
433    
434     =cut
435    
436     1;